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,117 +12,88 @@ __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')
def test_dlls(self):
import win32api import win32api
base = win32api.GetDllDirectory() base = win32api.GetDllDirectory()
errors = []
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(): def test_dbus(self):
import dbus import dbus
bus = dbus.SystemBus() bus = dbus.SystemBus()
if not bus.list_names(): self.assertTrue(bus.list_names(), 'Failed to list names on the system bus')
raise ValueError('Failed to list names on the system bus')
bus = dbus.SessionBus() bus = dbus.SessionBus()
if not bus.list_names(): self.assertTrue(bus.list_names(), 'Failed to list names on the session bus')
raise ValueError('Failed to list names on the session bus')
del bus del bus
fprint('dbus OK!')
def test_regex(): def test_regex(self):
import regex import regex
if regex.findall(r'(?i)(a)(b)', 'ab cd AB 1a1b') != [('a', 'b'), ('A', 'B')]: self.assertEqual(regex.findall(r'(?i)(a)(b)', 'ab cd AB 1a1b'), [('a', 'b'), ('A', 'B')])
raise ValueError('regex module failed on a simple search')
fprint('regex OK!')
def test_lzma(): def test_lzma(self):
from lzma.xz import test_lzma2 from lzma.xz import test_lzma2
test_lzma2() test_lzma2()
fprint('lzma OK!')
def test_html5lib(): def test_html5lib(self):
import html5lib.html5parser # noqa import html5lib.html5parser # noqa
from html5lib import parse # noqa from html5lib import parse # noqa
fprint('html5lib OK!')
def test_spell(): def test_spell(self):
from calibre.spell.dictionary import test_dictionaries from calibre.spell.dictionary import test_dictionaries
test_dictionaries() test_dictionaries()
fprint('hunspell OK!')
def test_plugins(): def test_plugins(self):
bad = []
for name in plugins: for name in plugins:
mod, err = plugins[name] mod, err = plugins[name]
if err or not mod: self.assertFalse(err or not mod, 'Failed to load plugin: ' + name + ' with error:\n' + err)
bad.append((name, err))
if bad:
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_lxml(self):
from calibre.utils.cleantext import test_clean_xml_chars from calibre.utils.cleantext import test_clean_xml_chars
test_clean_xml_chars() test_clean_xml_chars()
from lxml import etree from lxml import etree
raw = '<a/>' raw = '<a/>'
root = etree.fromstring(raw) root = etree.fromstring(raw)
if etree.tostring(root) == raw: self.assertEqual(etree.tostring(root), raw)
fprint('lxml OK!')
else:
raise RuntimeError('lxml failed')
def test_certgen(): def test_certgen(self):
from calibre.utils.certgen import create_key_pair from calibre.utils.certgen import create_key_pair
create_key_pair() create_key_pair()
def test_fsevents(): @unittest.skipUnless(isosx, 'FSEvents only present on OS X')
def test_fsevents(self):
from fsevents import Observer, Stream from fsevents import Observer, Stream
del Observer, Stream del Observer, Stream
fprint('macfsevents OK!')
def test_winutil(): @unittest.skipUnless(iswindows, 'winutil is windows only')
def test_winutil(self):
from calibre.constants import plugins from calibre.constants import plugins
winutil = plugins['winutil'][0] winutil = plugins['winutil'][0]
for x in winutil.argv(): for x in winutil.argv():
if not isinstance(x, unicode): self.assertTrue(isinstance(x, unicode), 'argv() not returning unicode string')
raise ValueError('argv() not returning unicode string')
fprint('winutil OK!')
def test_sqlite(): def test_sqlite(self):
import sqlite3 import sqlite3
conn = sqlite3.connect(':memory:') conn = sqlite3.connect(':memory:')
from calibre.library.sqlite import load_c_extensions from calibre.library.sqlite import load_c_extensions
if not load_c_extensions(conn, True): self.assertTrue(load_c_extensions(conn, True), 'Failed to load sqlite extension')
raise RuntimeError('Failed to load sqlite extension')
fprint('sqlite OK!')
def test_apsw(): def test_apsw(self):
import apsw import apsw
conn = apsw.Connection(':memory:') conn = apsw.Connection(':memory:')
conn.close() conn.close()
fprint('apsw OK!')
def test_image_formats(): def test_qt(self):
# Must be run before QApplication is constructed # Must be run before QApplication is constructed
# Test that the image formats are available without a QApplication being # Test that the image formats are available without a QApplication being
# constructed # constructed
@ -136,30 +107,23 @@ def test_image_formats():
# Run the imaging tests # Run the imaging tests
test() test()
def test_qt():
test_image_formats()
from calibre.gui2 import Application from calibre.gui2 import Application
from PyQt5.Qt import (QImageReader, QNetworkAccessManager, QFontDatabase) from PyQt5.Qt import (QImageReader, QNetworkAccessManager, QFontDatabase)
from PyQt5.QtWebKitWidgets import QWebView from PyQt5.QtWebKitWidgets import QWebView
os.environ.pop('DISPLAY', None) os.environ.pop('DISPLAY', None)
app = Application([], headless=islinux) app = Application([], headless=islinux)
if len(QFontDatabase().families()) < 5: self.assertGreaterEqual(len(QFontDatabase().families()), 5, 'The QPA headless plugin is not able to locate enough system fonts via fontconfig')
raise RuntimeError('The QPA headless plugin is not able to locate enough system fonts via fontconfig')
fmts = set(map(unicode, QImageReader.supportedImageFormats())) fmts = set(map(unicode, QImageReader.supportedImageFormats()))
testf = set(['jpg', 'png', 'svg', 'ico', 'gif']) testf = set(['jpg', 'png', 'svg', 'ico', 'gif'])
if testf.intersection(fmts) != testf: self.assertEqual(testf.intersection(fmts), testf, "Qt doesn't seem to be able to load its image plugins")
raise RuntimeError(
"Qt doesn't seem to be able to load its image plugins")
QWebView() QWebView()
del QWebView del QWebView
na = QNetworkAccessManager() na = QNetworkAccessManager()
if not hasattr(na, 'sslErrors'): self.assertTrue(hasattr(na, 'sslErrors'), 'Qt not compiled with openssl')
raise RuntimeError('Qt not compiled with openssl')
del na del na
del app del app
fprint('Qt OK!')
def test_imaging(): def test_imaging(self):
from PIL import Image from PIL import Image
try: try:
import _imaging, _imagingmath, _imagingft import _imaging, _imagingmath, _imagingft
@ -168,147 +132,97 @@ def test_imaging():
from PIL import _imaging, _imagingmath, _imagingft from PIL import _imaging, _imagingmath, _imagingft
_imaging, _imagingmath, _imagingft _imaging, _imagingmath, _imagingft
i = Image.open(I('lt.png', allow_user_override=False)) i = Image.open(I('lt.png', allow_user_override=False))
if i.size < (20, 20): self.assertGreaterEqual(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')
def test_file_dialog_helper(self):
from calibre.gui2.win_file_dialogs import test from calibre.gui2.win_file_dialogs import test
test() test()
print('File dialog helper OK!')
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
test_build()
fprint('ICU OK!')
def test_dukpy():
fprint('Testing dukpy')
from duktape import test_build
test_build()
fprint('dukpy OK!')
def test_wpd():
wpd = plugins['wpd'][0] wpd = plugins['wpd'][0]
try: try:
wpd.init('calibre', 1, 1, 1) wpd.init('calibre', 1, 1, 1)
except wpd.NoWPD: except wpd.NoWPD:
fprint('This computer does not have WPD') pass
else: else:
wpd.uninit() wpd.uninit()
fprint('WPD OK!')
def test_tokenizer(): def test_tinycss_tokenizer(self):
fprint('Testing tinycss tokenizer')
from tinycss.tokenizer import c_tokenize_flat from tinycss.tokenizer import c_tokenize_flat
if c_tokenize_flat is None: self.assertIsNotNone(c_tokenize_flat, 'tinycss C tokenizer not loaded')
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(): @unittest.skipUnless(getattr(sys, 'frozen', False), 'Only makes sense to test executables in frozen builds')
def test_executables(self):
from calibre.utils.ipc.launch import Worker from calibre.utils.ipc.launch import Worker
if getattr(sys, 'frozen', False): from calibre.ebooks.pdf.pdftohtml import PDFTOHTML
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):
def test_netifaces():
import netifaces import netifaces
if len(netifaces.interfaces()) < 1: self.assertGreaterEqual(netifaces.interfaces(), 1, 'netifaces could find no network interfaces')
raise ValueError('netifaces could find no network interfaces')
fprint('netifaces OK!')
def test_psutil(): def test_psutil(self):
import psutil import psutil
psutil.Process(os.getpid()) psutil.Process(os.getpid())
fprint('psutil OK!')
def test_podofo(): def test_podofo(self):
from calibre.utils.podofo import test_podofo as dotest from calibre.utils.podofo import test_podofo as dotest
dotest() dotest()
fprint('podofo OK!')
def test_terminal(): @unittest.skipIf(iswindows, 'readline not available on windows')
def test_terminal(self):
import readline import readline
del readline del readline
fprint('readline OK!')
def test_markdown(): def test_markdown(self):
from calibre.ebooks.markdown import Markdown from calibre.ebooks.markdown import Markdown
Markdown(extensions=['extra']) Markdown(extensions=['extra'])
from calibre.library.comments import sanitize_html from calibre.library.comments import sanitize_html
sanitize_html(b'''<script>moo</script>xxx<img src="http://moo.com/x.jpg">''') sanitize_html(b'''<script>moo</script>xxx<img src="http://moo.com/x.jpg">''')
fprint('Markdown OK!')
def test_image_compression(): def test_image_compression(self):
from calibre.utils.img import test from calibre.utils.img import test
test() test()
fprint('Image compression OK!')
def test_openssl(): def test_openssl(self):
import ssl import ssl
ssl.PROTOCOL_TLSv1_2 ssl.PROTOCOL_TLSv1_2
if isosx: if isosx:
cafile = ssl.get_default_verify_paths().cafile 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): if not cafile or not cafile.endswith('/mozilla-ca-certs.pem') or not os.access(cafile, os.R_OK):
raise ValueError('Mozilla CA certs not loaded') self.assert_('Mozilla CA certs not loaded')
fprint('SSL OK!')
def find_tests():
ans = unittest.defaultTestLoader.loadTestsFromTestCase(BuildTest)
from calibre.utils.icu_test import find_tests
import duktape.tests as dtests
ans.addTests(find_tests())
ans.addTests(unittest.defaultTestLoader.loadTestsFromModule(dtests))
from tinycss.tests.main import find_tests
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()