Change the build tests to use the unit testing framework

This commit is contained in:
Kovid Goyal 2016-06-24 08:34:54 +05:30
parent c64c8fe69e
commit 8a977e02d1

View File

@ -12,303 +12,217 @@ __docformat__ = 'restructuredtext en'
Test a binary calibre build to ensure that all needed binary images/libraries have loaded. Test a binary calibre build to ensure that all needed binary images/libraries have loaded.
''' '''
import os, ctypes, sys import os, ctypes, sys, unittest
from calibre.constants import plugins, iswindows, islinux, isosx from calibre.constants import plugins, iswindows, islinux, isosx
def fprint(*args, **kwargs): class BuildTest(unittest.TestCase):
print(*args, **kwargs)
sys.stdout.flush()
def test_dlls(): @unittest.skipUnless(iswindows, 'DLL loading needs testing only on windows')
import win32api def test_dlls(self):
base = win32api.GetDllDirectory() import win32api
errors = [] base = win32api.GetDllDirectory()
for x in os.listdir(base): for x in os.listdir(base):
if x.lower().endswith('.dll'): if x.lower().endswith('.dll'):
try: try:
ctypes.WinDLL(os.path.join(base, x)) ctypes.WinDLL(os.path.join(base, x))
except Exception as err: except Exception as err:
errors.append('Failed to load DLL %s with error: %s' % (x, err)) self.assertTrue(False, 'Failed to load DLL %s with error: %s' % (x, err))
fprint(errors[-1])
if errors:
fprint('Loading %d dll(s) failed!' % len(errors))
raise SystemExit(1)
fprint('DLLs OK!')
@unittest.skipUnless(islinux, 'DBUS only used on linux')
def test_dbus(self):
import dbus
bus = dbus.SystemBus()
self.assertTrue(bus.list_names(), 'Failed to list names on the system bus')
bus = dbus.SessionBus()
self.assertTrue(bus.list_names(), 'Failed to list names on the session bus')
del bus
def test_dbus(): def test_regex(self):
import dbus import regex
bus = dbus.SystemBus() self.assertEqual(regex.findall(r'(?i)(a)(b)', 'ab cd AB 1a1b'), [('a', 'b'), ('A', 'B')])
if not bus.list_names():
raise ValueError('Failed to list names on the system bus')
bus = dbus.SessionBus()
if not bus.list_names():
raise ValueError('Failed to list names on the session bus')
del bus
fprint('dbus OK!')
def test_regex(): def test_lzma(self):
import regex from lzma.xz import test_lzma2
if regex.findall(r'(?i)(a)(b)', 'ab cd AB 1a1b') != [('a', 'b'), ('A', 'B')]: test_lzma2()
raise ValueError('regex module failed on a simple search')
fprint('regex OK!')
def test_lzma(): def test_html5lib(self):
from lzma.xz import test_lzma2 import html5lib.html5parser # noqa
test_lzma2() from html5lib import parse # noqa
fprint('lzma OK!')
def test_html5lib(): def test_spell(self):
import html5lib.html5parser # noqa from calibre.spell.dictionary import test_dictionaries
from html5lib import parse # noqa test_dictionaries()
fprint('html5lib OK!')
def test_spell(): def test_plugins(self):
from calibre.spell.dictionary import test_dictionaries for name in plugins:
test_dictionaries() mod, err = plugins[name]
fprint('hunspell OK!') self.assertFalse(err or not mod, 'Failed to load plugin: ' + name + ' with error:\n' + err)
def test_plugins(): def test_lxml(self):
bad = [] from calibre.utils.cleantext import test_clean_xml_chars
for name in plugins: test_clean_xml_chars()
mod, err = plugins[name] from lxml import etree
if err or not mod: raw = '<a/>'
bad.append((name, err)) root = etree.fromstring(raw)
if bad: self.assertEqual(etree.tostring(root), raw)
for name, err in bad:
fprint('Failed to load plugin:', name, 'with error:\n', err, '\n')
raise SystemExit(1)
fprint('Loaded all plugins successfully!')
def test_lxml(): def test_certgen(self):
from calibre.utils.cleantext import test_clean_xml_chars from calibre.utils.certgen import create_key_pair
test_clean_xml_chars() create_key_pair()
from lxml import etree
raw = '<a/>'
root = etree.fromstring(raw)
if etree.tostring(root) == raw:
fprint('lxml OK!')
else:
raise RuntimeError('lxml failed')
def test_certgen(): @unittest.skipUnless(isosx, 'FSEvents only present on OS X')
from calibre.utils.certgen import create_key_pair def test_fsevents(self):
create_key_pair() from fsevents import Observer, Stream
del Observer, Stream
def test_fsevents(): @unittest.skipUnless(iswindows, 'winutil is windows only')
from fsevents import Observer, Stream def test_winutil(self):
del Observer, Stream from calibre.constants import plugins
fprint('macfsevents OK!') winutil = plugins['winutil'][0]
for x in winutil.argv():
self.assertTrue(isinstance(x, unicode), 'argv() not returning unicode string')
def test_winutil(): def test_sqlite(self):
from calibre.constants import plugins import sqlite3
winutil = plugins['winutil'][0] conn = sqlite3.connect(':memory:')
for x in winutil.argv(): from calibre.library.sqlite import load_c_extensions
if not isinstance(x, unicode): self.assertTrue(load_c_extensions(conn, True), 'Failed to load sqlite extension')
raise ValueError('argv() not returning unicode string')
fprint('winutil OK!')
def test_sqlite(): def test_apsw(self):
import sqlite3 import apsw
conn = sqlite3.connect(':memory:') conn = apsw.Connection(':memory:')
from calibre.library.sqlite import load_c_extensions conn.close()
if not load_c_extensions(conn, True):
raise RuntimeError('Failed to load sqlite extension')
fprint('sqlite OK!')
def test_apsw(): def test_qt(self):
import apsw # Must be run before QApplication is constructed
conn = apsw.Connection(':memory:') # Test that the image formats are available without a QApplication being
conn.close() # constructed
fprint('apsw OK!') from calibre.utils.img import image_from_data, image_to_data, test
data = I('blank.png', allow_user_override=False, data=True)
img = image_from_data(data)
image_from_data(P('catalog/mastheadImage.gif', allow_user_override=False, data=True))
for fmt in 'png bmp jpeg'.split():
d = image_to_data(img, fmt=fmt)
image_from_data(d)
# Run the imaging tests
test()
def test_image_formats(): from calibre.gui2 import Application
# Must be run before QApplication is constructed from PyQt5.Qt import (QImageReader, QNetworkAccessManager, QFontDatabase)
# Test that the image formats are available without a QApplication being from PyQt5.QtWebKitWidgets import QWebView
# constructed os.environ.pop('DISPLAY', None)
from calibre.utils.img import image_from_data, image_to_data, test app = Application([], headless=islinux)
data = I('blank.png', allow_user_override=False, data=True) self.assertGreaterEqual(len(QFontDatabase().families()), 5, 'The QPA headless plugin is not able to locate enough system fonts via fontconfig')
img = image_from_data(data) fmts = set(map(unicode, QImageReader.supportedImageFormats()))
image_from_data(P('catalog/mastheadImage.gif', allow_user_override=False, data=True)) testf = set(['jpg', 'png', 'svg', 'ico', 'gif'])
for fmt in 'png bmp jpeg'.split(): self.assertEqual(testf.intersection(fmts), testf, "Qt doesn't seem to be able to load its image plugins")
d = image_to_data(img, fmt=fmt) QWebView()
image_from_data(d) del QWebView
# Run the imaging tests na = QNetworkAccessManager()
test() self.assertTrue(hasattr(na, 'sslErrors'), 'Qt not compiled with openssl')
del na
del app
def test_qt(): def test_imaging(self):
test_image_formats() from PIL import Image
from calibre.gui2 import Application try:
from PyQt5.Qt import (QImageReader, QNetworkAccessManager, QFontDatabase) import _imaging, _imagingmath, _imagingft
from PyQt5.QtWebKitWidgets import QWebView _imaging, _imagingmath, _imagingft
os.environ.pop('DISPLAY', None) except ImportError:
app = Application([], headless=islinux) from PIL import _imaging, _imagingmath, _imagingft
if len(QFontDatabase().families()) < 5:
raise RuntimeError('The QPA headless plugin is not able to locate enough system fonts via fontconfig')
fmts = set(map(unicode, QImageReader.supportedImageFormats()))
testf = set(['jpg', 'png', 'svg', 'ico', 'gif'])
if testf.intersection(fmts) != testf:
raise RuntimeError(
"Qt doesn't seem to be able to load its image plugins")
QWebView()
del QWebView
na = QNetworkAccessManager()
if not hasattr(na, 'sslErrors'):
raise RuntimeError('Qt not compiled with openssl')
del na
del app
fprint('Qt OK!')
def test_imaging():
from PIL import Image
try:
import _imaging, _imagingmath, _imagingft
_imaging, _imagingmath, _imagingft _imaging, _imagingmath, _imagingft
except ImportError: i = Image.open(I('lt.png', allow_user_override=False))
from PIL import _imaging, _imagingmath, _imagingft self.assertGreaterEqual(i.size, (20, 20))
_imaging, _imagingmath, _imagingft
i = Image.open(I('lt.png', allow_user_override=False))
if i.size < (20, 20):
raise RuntimeError('PIL choked!')
fprint('PIL OK!')
def test_file_dialog_helper(): @unittest.skipUnless(iswindows, 'File dialog helper only used on windows')
from calibre.gui2.win_file_dialogs import test def test_file_dialog_helper(self):
test() from calibre.gui2.win_file_dialogs import test
print('File dialog helper OK!') test()
def test_unrar(): def test_unrar(self):
from calibre.utils.unrar import test_basic from calibre.utils.unrar import test_basic
test_basic() test_basic()
fprint('Unrar OK!')
def test_icu(): @unittest.skipUnless(iswindows, 'WPD is windows only')
fprint('Testing ICU') def test_wpd(self):
from calibre.utils.icu_test import test_build wpd = plugins['wpd'][0]
test_build() try:
fprint('ICU OK!') wpd.init('calibre', 1, 1, 1)
except wpd.NoWPD:
pass
else:
wpd.uninit()
def test_dukpy(): def test_tinycss_tokenizer(self):
fprint('Testing dukpy') from tinycss.tokenizer import c_tokenize_flat
from duktape import test_build self.assertIsNotNone(c_tokenize_flat, 'tinycss C tokenizer not loaded')
test_build()
fprint('dukpy OK!')
def test_wpd(): @unittest.skipUnless(getattr(sys, 'frozen', False), 'Only makes sense to test executables in frozen builds')
wpd = plugins['wpd'][0] def test_executables(self):
try: from calibre.utils.ipc.launch import Worker
wpd.init('calibre', 1, 1, 1) from calibre.ebooks.pdf.pdftohtml import PDFTOHTML
except wpd.NoWPD:
fprint('This computer does not have WPD')
else:
wpd.uninit()
fprint('WPD OK!')
def test_tokenizer():
fprint('Testing tinycss tokenizer')
from tinycss.tokenizer import c_tokenize_flat
if c_tokenize_flat is None:
raise ValueError('tinycss C tokenizer not loaded')
import tinycss.tests.main as m
if getattr(m, '__file__', None) and os.path.exists(m.__file__):
m.run_tests(for_build=True)
fprint('tinycss tokenizer OK!')
def test_executables():
from calibre.utils.ipc.launch import Worker
if getattr(sys, 'frozen', False):
w = Worker({}) w = Worker({})
if not os.path.exists(w.executable): self.assertTrue(os.path.exists(w.executable), 'calibre-parallel (%s) does not exist' % w.executable)
raise SystemExit('calibre-parallel (%s) does not exist' % w.executable) self.assertTrue(os.path.exists(w.gui_executable), 'calibre-parallel-gui (%s) does not exist' % w.gui_executable)
if not os.path.exists(w.gui_executable): self.assertTrue(os.path.exists(PDFTOHTML), 'pdftohtml (%s) does not exist' % PDFTOHTML)
raise SystemExit('calibre-parallel-gui (%s) does not exist' % w.gui_executable)
if iswindows: if iswindows:
from calibre.devices.usbms.device import eject_exe from calibre.devices.usbms.device import eject_exe
if not os.path.exists(eject_exe()): self.assertTrue(os.path.exists(eject_exe()), 'calibre-eject.exe (%s) does not exist' % eject_exe())
raise SystemExit('calibre-eject.exe (%s) does not exist' % eject_exe())
from calibre.ebooks.pdf.pdftohtml import PDFTOHTML
if not os.path.exists(PDFTOHTML):
raise SystemExit('pdftohtml (%s) does not exist' % PDFTOHTML)
fprint('executables OK!') def test_netifaces(self):
import netifaces
self.assertGreaterEqual(netifaces.interfaces(), 1, 'netifaces could find no network interfaces')
def test_netifaces(): def test_psutil(self):
import netifaces import psutil
if len(netifaces.interfaces()) < 1: psutil.Process(os.getpid())
raise ValueError('netifaces could find no network interfaces')
fprint('netifaces OK!')
def test_psutil(): def test_podofo(self):
import psutil from calibre.utils.podofo import test_podofo as dotest
psutil.Process(os.getpid()) dotest()
fprint('psutil OK!')
def test_podofo(): @unittest.skipIf(iswindows, 'readline not available on windows')
from calibre.utils.podofo import test_podofo as dotest def test_terminal(self):
dotest() import readline
fprint('podofo OK!') del readline
def test_terminal(): def test_markdown(self):
import readline from calibre.ebooks.markdown import Markdown
del readline Markdown(extensions=['extra'])
fprint('readline OK!') from calibre.library.comments import sanitize_html
sanitize_html(b'''<script>moo</script>xxx<img src="http://moo.com/x.jpg">''')
def test_markdown(): def test_image_compression(self):
from calibre.ebooks.markdown import Markdown from calibre.utils.img import test
Markdown(extensions=['extra']) test()
from calibre.library.comments import sanitize_html
sanitize_html(b'''<script>moo</script>xxx<img src="http://moo.com/x.jpg">''')
fprint('Markdown OK!')
def test_image_compression(): def test_openssl(self):
from calibre.utils.img import test import ssl
test() ssl.PROTOCOL_TLSv1_2
fprint('Image compression OK!') if isosx:
cafile = ssl.get_default_verify_paths().cafile
if not cafile or not cafile.endswith('/mozilla-ca-certs.pem') or not os.access(cafile, os.R_OK):
self.assert_('Mozilla CA certs not loaded')
def test_openssl(): def find_tests():
import ssl ans = unittest.defaultTestLoader.loadTestsFromTestCase(BuildTest)
ssl.PROTOCOL_TLSv1_2 from calibre.utils.icu_test import find_tests
if isosx: import duktape.tests as dtests
cafile = ssl.get_default_verify_paths().cafile ans.addTests(find_tests())
if not cafile or not cafile.endswith('/mozilla-ca-certs.pem') or not os.access(cafile, os.R_OK): ans.addTests(unittest.defaultTestLoader.loadTestsFromModule(dtests))
raise ValueError('Mozilla CA certs not loaded') from tinycss.tests.main import find_tests
fprint('SSL OK!') ans.addTests(find_tests())
return ans
class TestRunner(unittest.main):
def createTests(self):
self.test = find_tests()
def test(): def test():
if iswindows: result = TestRunner(verbosity=2, buffer=True, catchbreak=True, failfast=True, argv=sys.argv[:1], exit=False).result
test_dlls() if not result.wasSuccessful():
test_plugins() raise SystemExit(1)
test_executables()
test_image_compression()
test_lzma()
test_dukpy()
test_spell()
test_lxml()
test_openssl()
test_sqlite()
test_apsw()
test_imaging()
test_unrar()
test_certgen()
test_icu()
test_qt()
test_html5lib()
test_regex()
test_tokenizer()
test_netifaces()
test_psutil()
test_podofo()
test_markdown()
if islinux:
test_dbus()
if iswindows:
test_wpd()
test_winutil()
test_file_dialog_helper()
else:
test_terminal()
if isosx:
test_fsevents()
if __name__ == '__main__': if __name__ == '__main__':
test() test()