2008-08-24 14:37:40 +08:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""IPython Test Suite Runner.
|
2009-03-11 13:49:08 +08:00
|
|
|
|
2009-04-25 01:12:50 +08:00
|
|
|
This module provides a main entry point to a user script to test IPython
|
|
|
|
itself from the command line. There are two ways of running this script:
|
|
|
|
|
|
|
|
1. With the syntax `iptest all`. This runs our entire test suite by
|
2011-03-31 14:20:28 +08:00
|
|
|
calling this script (with different arguments) recursively. This
|
2009-04-25 01:12:50 +08:00
|
|
|
causes modules and package to be tested in different processes, using nose
|
|
|
|
or trial where appropriate.
|
|
|
|
2. With the regular nose syntax, like `iptest -vvs IPython`. In this form
|
|
|
|
the script simply calls nose, but with special command line flags and
|
|
|
|
plugins loaded.
|
|
|
|
|
2008-08-24 14:37:40 +08:00
|
|
|
"""
|
|
|
|
|
2009-03-11 13:49:08 +08:00
|
|
|
#-----------------------------------------------------------------------------
|
update copyright to 2011/20xx-2011
Closes #1033 (rebased to prevent recursive merge). Closes #2.
459 *.py files in :
39 empty files
176 files without copyright
36 have copyright but don't cite the dev team
208 have copyright and cite the dev team
-----------------------------------------
0 not up to date (cite dev team but not right year)
FYI, list of files that don't have copyright (and are not empty..)
[
'IPython/config/profile/cluster/ipython_config.py',
'IPython/config/profile/math/ipython_config.py',
'IPython/config/profile/pylab/ipython_config.py',
'IPython/config/profile/pysh/ipython_config.py',
'IPython/config/profile/python3/ipython_config.py',
'IPython/config/profile/sympy/ipython_config.py',
'IPython/core/shadowns.py',
'IPython/core/tests/refbug.py',
'IPython/core/tests/simpleerr.py',
'IPython/core/tests/tclass.py',
'IPython/core/tests/test_application.py',
'IPython/core/tests/test_autocall.py',
'IPython/core/tests/test_completer.py',
'IPython/core/tests/test_fakemodule.py',
'IPython/core/tests/test_formatters.py',
'IPython/core/tests/test_handlers.py',
'IPython/core/tests/test_history.py',
'IPython/core/tests/test_imports.py',
'IPython/core/tests/test_iplib.py',
'IPython/core/tests/test_logger.py',
'IPython/core/tests/test_magic.py',
'IPython/core/tests/test_plugin.py',
'IPython/core/tests/test_prefilter.py',
'IPython/core/tests/test_profile.py',
'IPython/core/tests/test_run.py',
'IPython/core/tests/test_splitinput.py',
'IPython/deathrow/astyle.py',
'IPython/deathrow/dtutils.py',
'IPython/deathrow/Gnuplot2.py',
'IPython/deathrow/GnuplotInteractive.py',
'IPython/deathrow/GnuplotRuntime.py',
'IPython/deathrow/gui/wx/ipshell_nonblocking.py',
'IPython/deathrow/gui/wx/ipython_history.py',
'IPython/deathrow/gui/wx/thread_ex.py',
'IPython/deathrow/ibrowse.py',
'IPython/deathrow/igrid.py',
'IPython/deathrow/ipipe.py',
'IPython/deathrow/ipy_defaults.py',
'IPython/deathrow/ipy_kitcfg.py',
'IPython/deathrow/ipy_legacy.py',
'IPython/deathrow/ipy_p4.py',
'IPython/deathrow/ipy_profile_none.py',
'IPython/deathrow/ipy_profile_numpy.py',
'IPython/deathrow/ipy_profile_scipy.py',
'IPython/deathrow/ipy_profile_sh.py',
'IPython/deathrow/ipy_traits_completer.py',
'IPython/deathrow/ipy_vimserver.py',
'IPython/deathrow/numeric_formats.py',
'IPython/deathrow/oldfrontend/process/__init__.py',
'IPython/deathrow/oldfrontend/wx/ipythonx.py',
'IPython/deathrow/scitedirector.py',
'IPython/deathrow/tests/test_prefilter.py',
'IPython/deathrow/twshell.py',
'IPython/extensions/__init__.py',
'IPython/extensions/autoreload.py',
'IPython/extensions/storemagic.py',
'IPython/extensions/tests/test_autoreload.py',
'IPython/external/__init__.py',
'IPython/external/argparse/__init__.py',
'IPython/external/decorator/__init__.py',
'IPython/external/decorators/__init__.py',
'IPython/external/decorators/_decorators.py',
'IPython/external/decorators/_numpy_testing_noseclasses.py',
'IPython/external/decorators/_numpy_testing_utils.py',
'IPython/external/guid/__init__.py',
'IPython/external/Itpl/__init__.py',
'IPython/external/mglob/__init__.py',
'IPython/external/mglob/_mglob.py',
'IPython/external/path/__init__.py',
'IPython/external/path/_path.py',
'IPython/external/pexpect/__init__.py',
'IPython/external/pyparsing/__init__.py',
'IPython/external/qt.py',
'IPython/external/qt_for_kernel.py',
'IPython/external/simplegeneric/__init__.py',
'IPython/external/simplegeneric/_simplegeneric.py',
'IPython/frontend/html/notebook/__init__.py',
'IPython/frontend/html/notebook/tests/test_kernelsession.py',
'IPython/frontend/qt/base_frontend_mixin.py',
'IPython/frontend/qt/console/ansi_code_processor.py',
'IPython/frontend/qt/console/bracket_matcher.py',
'IPython/frontend/qt/console/call_tip_widget.py',
'IPython/frontend/qt/console/completion_lexer.py',
'IPython/frontend/qt/console/completion_widget.py',
'IPython/frontend/qt/console/console_widget.py',
'IPython/frontend/qt/console/history_console_widget.py',
'IPython/frontend/qt/console/ipython_widget.py',
'IPython/frontend/qt/console/kill_ring.py',
'IPython/frontend/qt/console/mainwindow.py',
'IPython/frontend/qt/console/pygments_highlighter.py',
'IPython/frontend/qt/console/qtconsoleapp.py',
'IPython/frontend/qt/console/rich_ipython_widget.py',
'IPython/frontend/qt/console/styles.py',
'IPython/frontend/qt/console/tests/test_ansi_code_processor.py',
'IPython/frontend/qt/console/tests/test_completion_lexer.py',
'IPython/frontend/qt/console/tests/test_kill_ring.py',
'IPython/frontend/qt/kernelmanager.py',
'IPython/frontend/qt/rich_text.py',
'IPython/frontend/qt/svg.py',
'IPython/frontend/qt/util.py',
'IPython/kernel/__init__.py',
'IPython/lib/clipboard.py',
'IPython/lib/display.py',
'IPython/lib/irunner.py',
'IPython/lib/security.py',
'IPython/lib/tests/test_imports.py',
'IPython/lib/tests/test_irunner.py',
'IPython/lib/tests/test_irunner_pylab_magic.py',
'IPython/lib/tests/test_security.py',
'IPython/nbformat/v1/tests/nbexamples.py',
'IPython/nbformat/v1/tests/test_json.py',
'IPython/nbformat/v1/tests/test_nbbase.py',
'IPython/nbformat/v2/tests/nbexamples.py',
'IPython/nbformat/v2/tests/test_json.py',
'IPython/nbformat/v2/tests/test_nbbase.py',
'IPython/nbformat/v2/tests/test_nbpy.py',
'IPython/quarantine/clearcmd.py',
'IPython/quarantine/envpersist.py',
'IPython/quarantine/ext_rescapture.py',
'IPython/quarantine/ipy_app_completers.py',
'IPython/quarantine/ipy_completers.py',
'IPython/quarantine/ipy_editors.py',
'IPython/quarantine/ipy_exportdb.py',
'IPython/quarantine/ipy_extutil.py',
'IPython/quarantine/ipy_fsops.py',
'IPython/quarantine/ipy_gnuglobal.py',
'IPython/quarantine/ipy_jot.py',
'IPython/quarantine/ipy_lookfor.py',
'IPython/quarantine/ipy_profile_doctest.py',
'IPython/quarantine/ipy_pydb.py',
'IPython/quarantine/ipy_rehashdir.py',
'IPython/quarantine/ipy_render.py',
'IPython/quarantine/ipy_server.py',
'IPython/quarantine/ipy_signals.py',
'IPython/quarantine/ipy_synchronize_with.py',
'IPython/quarantine/ipy_system_conf.py',
'IPython/quarantine/ipy_which.py',
'IPython/quarantine/ipy_winpdb.py',
'IPython/quarantine/ipy_workdir.py',
'IPython/quarantine/jobctrl.py',
'IPython/quarantine/ledit.py',
'IPython/quarantine/win32clip.py',
'IPython/testing/mkdoctests.py',
'IPython/testing/plugin/dtexample.py',
'IPython/testing/plugin/ipdoctest.py',
'IPython/testing/plugin/iptest.py',
'IPython/testing/plugin/setup.py',
'IPython/testing/plugin/show_refs.py',
'IPython/testing/plugin/simple.py',
'IPython/testing/plugin/simplevars.py',
'IPython/testing/plugin/test_ipdoctest.py',
'IPython/testing/plugin/test_refs.py',
'IPython/testing/skipdoctest.py',
'IPython/testing/tests/test_decorators.py',
'IPython/utils/autoattr.py',
'IPython/utils/nested_context.py',
'IPython/utils/pickleshare.py',
'IPython/utils/py3compat.py',
'IPython/utils/PyColorize.py',
'IPython/utils/rlineimpl.py',
'IPython/utils/strdispatch.py',
'IPython/utils/tempdir.py',
'IPython/utils/tests/test_imports.py',
'IPython/utils/tests/test_wildcard.py',
'IPython/utils/upgradedir.py',
'IPython/zmq/completer.py',
'IPython/zmq/displayhook.py',
'IPython/zmq/entry_point.py',
'IPython/zmq/frontend.py',
'IPython/zmq/iostream.py',
'IPython/zmq/ipkernel.py',
'IPython/zmq/log.py',
'IPython/zmq/parentpoller.py',
'IPython/zmq/pykernel.py',
'IPython/zmq/pylab/backend_inline.py',
'IPython/zmq/zmqshell.py'
]
2011-11-23 22:26:28 +08:00
|
|
|
# Copyright (C) 2009-2011 The IPython Development Team
|
2010-01-30 08:24:13 +08:00
|
|
|
#
|
|
|
|
# Distributed under the terms of the BSD License. The full license is in
|
|
|
|
# the file COPYING, distributed as part of this software.
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Imports
|
2009-03-11 13:49:08 +08:00
|
|
|
#-----------------------------------------------------------------------------
|
2012-07-05 19:40:15 +08:00
|
|
|
from __future__ import print_function
|
2009-03-11 13:49:08 +08:00
|
|
|
|
2010-01-13 04:42:23 +08:00
|
|
|
# Stdlib
|
2012-06-11 09:05:52 +08:00
|
|
|
import glob
|
2009-04-25 01:12:50 +08:00
|
|
|
import os
|
|
|
|
import os.path as path
|
2013-09-06 06:37:30 +08:00
|
|
|
import re
|
2008-08-24 14:37:40 +08:00
|
|
|
import sys
|
|
|
|
import warnings
|
|
|
|
|
2010-01-13 04:42:23 +08:00
|
|
|
# Now, proceed to import nose itself
|
2008-08-24 14:37:40 +08:00
|
|
|
import nose.plugins.builtin
|
2012-02-10 03:52:20 +08:00
|
|
|
from nose.plugins.xunit import Xunit
|
|
|
|
from nose import SkipTest
|
2009-03-11 13:49:08 +08:00
|
|
|
from nose.core import TestProgram
|
2013-09-06 06:37:30 +08:00
|
|
|
from nose.plugins import Plugin
|
2008-08-24 14:37:40 +08:00
|
|
|
|
2010-01-13 04:42:23 +08:00
|
|
|
# Our own imports
|
2011-09-24 07:57:40 +08:00
|
|
|
from IPython.utils.importstring import import_item
|
2010-01-15 17:06:34 +08:00
|
|
|
from IPython.testing.plugin.ipdoctest import IPythonDoctest
|
2012-02-10 03:52:20 +08:00
|
|
|
from IPython.external.decorators import KnownFailure, knownfailureif
|
2008-08-24 14:37:40 +08:00
|
|
|
|
2009-04-26 00:04:56 +08:00
|
|
|
pjoin = path.join
|
|
|
|
|
2010-01-18 05:13:21 +08:00
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Globals
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
2010-01-08 08:04:08 +08:00
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Warnings control
|
|
|
|
#-----------------------------------------------------------------------------
|
2010-02-01 04:06:20 +08:00
|
|
|
|
2010-01-08 08:04:08 +08:00
|
|
|
# Twisted generates annoying warnings with Python 2.6, as will do other code
|
|
|
|
# that imports 'sets' as of today
|
|
|
|
warnings.filterwarnings('ignore', 'the sets module is deprecated',
|
|
|
|
DeprecationWarning )
|
|
|
|
|
2010-01-13 15:21:21 +08:00
|
|
|
# This one also comes from Twisted
|
|
|
|
warnings.filterwarnings('ignore', 'the sha module is deprecated',
|
|
|
|
DeprecationWarning)
|
|
|
|
|
2010-01-16 06:41:10 +08:00
|
|
|
# Wx on Fedora11 spits these out
|
|
|
|
warnings.filterwarnings('ignore', 'wxPython/wxWidgets release number mismatch',
|
|
|
|
UserWarning)
|
|
|
|
|
2012-02-10 03:52:20 +08:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Monkeypatch Xunit to count known failures as skipped.
|
|
|
|
# ------------------------------------------------------------------------------
|
2012-02-10 04:20:19 +08:00
|
|
|
def monkeypatch_xunit():
|
2012-02-10 03:52:20 +08:00
|
|
|
try:
|
|
|
|
knownfailureif(True)(lambda: None)()
|
|
|
|
except Exception as e:
|
|
|
|
KnownFailureTest = type(e)
|
|
|
|
|
|
|
|
def addError(self, test, err, capt=None):
|
|
|
|
if issubclass(err[0], KnownFailureTest):
|
|
|
|
err = (SkipTest,) + err[1:]
|
|
|
|
return self.orig_addError(test, err, capt)
|
|
|
|
|
|
|
|
Xunit.orig_addError = Xunit.addError
|
|
|
|
Xunit.addError = addError
|
|
|
|
|
2009-03-11 13:49:08 +08:00
|
|
|
#-----------------------------------------------------------------------------
|
2013-09-06 06:37:30 +08:00
|
|
|
# Check which dependencies are installed and greater than minimum version.
|
2009-03-11 13:49:08 +08:00
|
|
|
#-----------------------------------------------------------------------------
|
2011-09-24 07:57:40 +08:00
|
|
|
def extract_version(mod):
|
|
|
|
return mod.__version__
|
2009-03-11 13:49:08 +08:00
|
|
|
|
2011-09-24 07:57:40 +08:00
|
|
|
def test_for(item, min_version=None, callback=extract_version):
|
|
|
|
"""Test to see if item is importable, and optionally check against a minimum
|
|
|
|
version.
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2011-09-24 07:57:40 +08:00
|
|
|
If min_version is given, the default behavior is to check against the
|
|
|
|
`__version__` attribute of the item, but specifying `callback` allows you to
|
|
|
|
extract the value you are interested in. e.g::
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2011-09-24 07:57:40 +08:00
|
|
|
In [1]: import sys
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2011-09-24 07:57:40 +08:00
|
|
|
In [2]: from IPython.testing.iptest import test_for
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2011-09-24 07:57:40 +08:00
|
|
|
In [3]: test_for('sys', (2,6), callback=lambda sys: sys.version_info)
|
|
|
|
Out[3]: True
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2011-09-24 07:57:40 +08:00
|
|
|
"""
|
2009-04-26 03:27:03 +08:00
|
|
|
try:
|
2011-09-24 07:57:40 +08:00
|
|
|
check = import_item(item)
|
2010-01-17 06:50:08 +08:00
|
|
|
except (ImportError, RuntimeError):
|
2011-09-24 07:57:40 +08:00
|
|
|
# GTK reports Runtime error if it can't be initialized even if it's
|
2010-01-17 06:50:08 +08:00
|
|
|
# importable.
|
2009-04-26 03:27:03 +08:00
|
|
|
return False
|
|
|
|
else:
|
2011-02-28 13:06:02 +08:00
|
|
|
if min_version:
|
2011-09-24 07:57:40 +08:00
|
|
|
if callback:
|
|
|
|
# extra processing step to get version to compare
|
|
|
|
check = callback(check)
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2011-09-24 07:57:40 +08:00
|
|
|
return check >= min_version
|
2011-02-28 13:06:02 +08:00
|
|
|
else:
|
|
|
|
return True
|
2009-04-26 03:27:03 +08:00
|
|
|
|
2010-01-18 06:36:19 +08:00
|
|
|
# Global dict where we can store information on what we have and what we don't
|
|
|
|
# have available at test run time
|
|
|
|
have = {}
|
|
|
|
|
|
|
|
have['curses'] = test_for('_curses')
|
2011-04-11 15:22:11 +08:00
|
|
|
have['matplotlib'] = test_for('matplotlib')
|
2012-05-31 09:58:14 +08:00
|
|
|
have['numpy'] = test_for('numpy')
|
2011-09-24 07:57:40 +08:00
|
|
|
have['pexpect'] = test_for('IPython.external.pexpect')
|
2011-04-11 15:22:11 +08:00
|
|
|
have['pymongo'] = test_for('pymongo')
|
2012-05-23 05:38:59 +08:00
|
|
|
have['pygments'] = test_for('pygments')
|
2011-04-14 03:19:12 +08:00
|
|
|
have['qt'] = test_for('IPython.external.qt')
|
2012-05-31 09:58:14 +08:00
|
|
|
have['rpy2'] = test_for('rpy2')
|
2011-10-21 01:36:10 +08:00
|
|
|
have['sqlite3'] = test_for('sqlite3')
|
2012-05-31 13:01:34 +08:00
|
|
|
have['cython'] = test_for('Cython')
|
2012-06-08 05:18:42 +08:00
|
|
|
have['oct2py'] = test_for('oct2py')
|
2011-09-24 07:57:40 +08:00
|
|
|
have['tornado'] = test_for('tornado.version_info', (2,1,0), callback=None)
|
2012-12-19 05:13:02 +08:00
|
|
|
have['jinja2'] = test_for('jinja2')
|
2012-05-31 09:58:14 +08:00
|
|
|
have['wx'] = test_for('wx')
|
|
|
|
have['wx.aui'] = test_for('wx.aui')
|
2012-08-11 08:21:57 +08:00
|
|
|
have['azure'] = test_for('azure')
|
2013-07-01 07:06:22 +08:00
|
|
|
have['sphinx'] = test_for('sphinx')
|
2011-09-24 07:57:40 +08:00
|
|
|
|
2013-01-26 04:37:49 +08:00
|
|
|
min_zmq = (2,1,11)
|
|
|
|
|
2013-01-29 06:37:09 +08:00
|
|
|
have['zmq'] = test_for('zmq.pyzmq_version_info', min_zmq, callback=lambda x: x())
|
2009-04-26 03:27:03 +08:00
|
|
|
|
2010-01-18 05:13:21 +08:00
|
|
|
#-----------------------------------------------------------------------------
|
2013-09-06 06:37:30 +08:00
|
|
|
# Test suite definitions
|
2010-01-18 05:13:21 +08:00
|
|
|
#-----------------------------------------------------------------------------
|
2009-04-26 01:05:09 +08:00
|
|
|
|
2013-09-06 06:37:30 +08:00
|
|
|
test_group_names = ['parallel', 'kernel', 'kernel.inprocess', 'config', 'core',
|
|
|
|
'extensions', 'lib', 'terminal', 'testing', 'utils',
|
|
|
|
'nbformat', 'qt', 'html', 'nbconvert'
|
|
|
|
]
|
|
|
|
|
|
|
|
class TestSection(object):
|
|
|
|
def __init__(self, name, includes):
|
|
|
|
self.name = name
|
|
|
|
self.includes = includes
|
|
|
|
self.excludes = []
|
|
|
|
self.dependencies = []
|
|
|
|
self.enabled = True
|
|
|
|
|
|
|
|
def exclude(self, module):
|
|
|
|
if not module.startswith('IPython'):
|
|
|
|
module = self.includes[0] + "." + module
|
|
|
|
self.excludes.append(module.replace('.', os.sep))
|
|
|
|
|
|
|
|
def requires(self, *packages):
|
|
|
|
self.dependencies.extend(packages)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def will_run(self):
|
|
|
|
return self.enabled and all(have[p] for p in self.dependencies)
|
|
|
|
|
|
|
|
# Name -> (include, exclude, dependencies_met)
|
|
|
|
test_sections = {n:TestSection(n, ['IPython.%s' % n]) for n in test_group_names}
|
|
|
|
|
|
|
|
# Exclusions and dependencies
|
|
|
|
# ---------------------------
|
|
|
|
|
|
|
|
# core:
|
|
|
|
sec = test_sections['core']
|
|
|
|
if not have['sqlite3']:
|
|
|
|
sec.exclude('tests.test_history')
|
|
|
|
sec.exclude('history')
|
|
|
|
if not have['matplotlib']:
|
|
|
|
sec.exclude('pylabtools'),
|
|
|
|
sec.exclude('tests.test_pylabtools')
|
|
|
|
|
|
|
|
# lib:
|
|
|
|
sec = test_sections['lib']
|
|
|
|
if not have['wx']:
|
|
|
|
sec.exclude('inputhookwx')
|
|
|
|
if not have['pexpect']:
|
|
|
|
sec.exclude('irunner')
|
|
|
|
sec.exclude('tests.test_irunner')
|
|
|
|
if not have['zmq']:
|
|
|
|
sec.exclude('kernel')
|
|
|
|
# We do this unconditionally, so that the test suite doesn't import
|
|
|
|
# gtk, changing the default encoding and masking some unicode bugs.
|
|
|
|
sec.exclude('inputhookgtk')
|
|
|
|
# Testing inputhook will need a lot of thought, to figure out
|
|
|
|
# how to have tests that don't lock up with the gui event
|
|
|
|
# loops in the picture
|
|
|
|
sec.exclude('inputhook')
|
|
|
|
|
|
|
|
# testing:
|
|
|
|
sec = test_sections['lib']
|
|
|
|
# This guy is probably attic material
|
|
|
|
sec.exclude('mkdoctests')
|
|
|
|
# These have to be skipped on win32 because the use echo, rm, cd, etc.
|
|
|
|
# See ticket https://github.com/ipython/ipython/issues/87
|
|
|
|
if sys.platform == 'win32':
|
|
|
|
sec.exclude('plugin.test_exampleip')
|
|
|
|
sec.exclude('plugin.dtexample')
|
|
|
|
|
|
|
|
# terminal:
|
|
|
|
if (not have['pexpect']) or (not have['zmq']):
|
|
|
|
test_sections['terminal'].exclude('console')
|
|
|
|
|
|
|
|
# parallel
|
|
|
|
sec = test_sections['parallel']
|
|
|
|
sec.requires('zmq')
|
|
|
|
if not have['pymongo']:
|
|
|
|
sec.exclude('controller.mongodb')
|
|
|
|
sec.exclude('tests.test_mongodb')
|
|
|
|
|
|
|
|
# kernel:
|
|
|
|
sec = test_sections['kernel']
|
|
|
|
sec.requires('zmq')
|
|
|
|
# The in-process kernel tests are done in a separate section
|
|
|
|
sec.exclude('inprocess')
|
|
|
|
# importing gtk sets the default encoding, which we want to avoid
|
|
|
|
sec.exclude('zmq.gui.gtkembed')
|
|
|
|
if not have['matplotlib']:
|
|
|
|
sec.exclude('zmq.pylab')
|
|
|
|
|
|
|
|
# kernel.inprocess:
|
|
|
|
test_sections['kernel.inprocess'].requires('zmq')
|
|
|
|
|
|
|
|
# extensions:
|
|
|
|
sec = test_sections['extensions']
|
|
|
|
if not have['cython']:
|
|
|
|
sec.exclude('cythonmagic')
|
|
|
|
sec.exclude('tests.test_cythonmagic')
|
|
|
|
if not have['oct2py']:
|
|
|
|
sec.exclude('octavemagic')
|
|
|
|
sec.exclude('tests.test_octavemagic')
|
|
|
|
if not have['rpy2'] or not have['numpy']:
|
|
|
|
sec.exclude('rmagic')
|
|
|
|
sec.exclude('tests.test_rmagic')
|
|
|
|
# autoreload does some strange stuff, so move it to its own test section
|
|
|
|
sec.exclude('autoreload')
|
|
|
|
sec.exclude('tests.test_autoreload')
|
|
|
|
test_sections['autoreload'] = TestSection('autoreload',
|
|
|
|
['IPython.extensions.autoreload', 'IPython.extensions.tests.test_autoreload'])
|
|
|
|
test_group_names.append('autoreload')
|
|
|
|
|
|
|
|
# qt:
|
|
|
|
test_sections['qt'].requires('zmq', 'qt', 'pygments')
|
|
|
|
|
|
|
|
# html:
|
|
|
|
sec = test_sections['html']
|
|
|
|
sec.requires('zmq', 'tornado')
|
|
|
|
# The notebook 'static' directory contains JS, css and other
|
|
|
|
# files for web serving. Occasionally projects may put a .py
|
|
|
|
# file in there (MathJax ships a conf.py), so we might as
|
|
|
|
# well play it safe and skip the whole thing.
|
|
|
|
sec.exclude('static')
|
|
|
|
sec.exclude('fabfile')
|
|
|
|
if not have['jinja2']:
|
|
|
|
sec.exclude('notebookapp')
|
|
|
|
if not have['azure']:
|
|
|
|
sec.exclude('services.notebooks.azurenbmanager')
|
|
|
|
|
|
|
|
# config:
|
|
|
|
# Config files aren't really importable stand-alone
|
|
|
|
test_sections['config'].exclude('profile')
|
|
|
|
|
|
|
|
# nbconvert:
|
|
|
|
sec = test_sections['nbconvert']
|
|
|
|
sec.requires('pygments', 'jinja2', 'sphinx')
|
|
|
|
# Exclude nbconvert directories containing config files used to test.
|
|
|
|
# Executing the config files with iptest would cause an exception.
|
|
|
|
sec.exclude('tests.files')
|
|
|
|
sec.exclude('exporters.tests.files')
|
2013-09-20 06:25:00 +08:00
|
|
|
if not have['tornado']:
|
|
|
|
sec.exclude('nbconvert.post_processors.serve')
|
|
|
|
sec.exclude('nbconvert.post_processors.tests.test_serve')
|
2010-01-18 06:36:19 +08:00
|
|
|
|
2013-09-06 06:37:30 +08:00
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Functions and classes
|
|
|
|
#-----------------------------------------------------------------------------
|
2010-02-01 04:06:20 +08:00
|
|
|
|
2013-09-06 06:37:30 +08:00
|
|
|
def check_exclusions_exist():
|
2013-09-07 02:02:41 +08:00
|
|
|
from IPython.utils.path import get_ipython_package_dir
|
|
|
|
from IPython.utils.warn import warn
|
2013-09-06 06:37:30 +08:00
|
|
|
parent = os.path.dirname(get_ipython_package_dir())
|
|
|
|
for sec in test_sections:
|
|
|
|
for pattern in sec.exclusions:
|
|
|
|
fullpath = pjoin(parent, pattern)
|
|
|
|
if not os.path.exists(fullpath) and not glob.glob(fullpath + '.*'):
|
|
|
|
warn("Excluding nonexistent file: %r" % pattern)
|
2010-02-01 04:06:20 +08:00
|
|
|
|
2013-09-06 06:37:30 +08:00
|
|
|
|
|
|
|
class ExclusionPlugin(Plugin):
|
|
|
|
"""A nose plugin to effect our exclusions of files and directories.
|
2010-01-13 09:36:00 +08:00
|
|
|
"""
|
2013-09-06 06:37:30 +08:00
|
|
|
name = 'exclusions'
|
|
|
|
score = 3000 # Should come before any other plugins
|
2013-01-30 11:27:02 +08:00
|
|
|
|
2013-09-06 06:37:30 +08:00
|
|
|
def __init__(self, exclude_patterns=None):
|
|
|
|
"""
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
|
|
|
|
exclude_patterns : sequence of strings, optional
|
|
|
|
These patterns are compiled as regular expressions, subsequently used
|
|
|
|
to exclude any filename which matches them from inclusion in the test
|
|
|
|
suite (using pattern.search(), NOT pattern.match() ).
|
|
|
|
"""
|
|
|
|
|
|
|
|
if exclude_patterns is None:
|
|
|
|
exclude_patterns = []
|
|
|
|
self.exclude_patterns = [re.compile(p) for p in exclude_patterns]
|
|
|
|
super(ExclusionPlugin, self).__init__()
|
|
|
|
|
|
|
|
def options(self, parser, env=os.environ):
|
|
|
|
Plugin.options(self, parser, env)
|
2012-06-01 02:56:06 +08:00
|
|
|
|
2013-09-06 06:37:30 +08:00
|
|
|
def configure(self, options, config):
|
|
|
|
Plugin.configure(self, options, config)
|
|
|
|
# Override nose trying to disable plugin.
|
|
|
|
self.enabled = True
|
|
|
|
|
|
|
|
def wantFile(self, filename):
|
|
|
|
"""Return whether the given filename should be scanned for tests.
|
|
|
|
"""
|
|
|
|
if any(pat.search(filename) for pat in self.exclude_patterns):
|
|
|
|
return False
|
|
|
|
return None
|
|
|
|
|
|
|
|
def wantDirectory(self, directory):
|
|
|
|
"""Return whether the given directory should be scanned for tests.
|
|
|
|
"""
|
|
|
|
if any(pat.search(directory) for pat in self.exclude_patterns):
|
|
|
|
return False
|
|
|
|
return None
|
2010-01-08 08:04:08 +08:00
|
|
|
|
|
|
|
|
2009-04-25 01:12:50 +08:00
|
|
|
def run_iptest():
|
|
|
|
"""Run the IPython test suite using nose.
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2009-04-25 01:12:50 +08:00
|
|
|
This function is called when this script is **not** called with the form
|
|
|
|
`iptest all`. It simply calls nose with appropriate command line flags
|
|
|
|
and accepts all of the standard nose arguments.
|
2008-08-24 14:37:40 +08:00
|
|
|
"""
|
2012-02-10 04:20:19 +08:00
|
|
|
# Apply our monkeypatch to Xunit
|
2012-02-14 07:17:05 +08:00
|
|
|
if '--with-xunit' in sys.argv and not hasattr(Xunit, 'orig_addError'):
|
2012-02-10 04:20:19 +08:00
|
|
|
monkeypatch_xunit()
|
2008-08-24 14:37:40 +08:00
|
|
|
|
2011-10-04 22:14:41 +08:00
|
|
|
warnings.filterwarnings('ignore',
|
2008-08-24 14:37:40 +08:00
|
|
|
'This will be removed soon. Use IPython.testing.util instead')
|
2013-06-30 05:29:51 +08:00
|
|
|
|
2013-09-12 00:54:45 +08:00
|
|
|
arg1 = sys.argv[1]
|
|
|
|
if arg1 in test_sections:
|
|
|
|
section = test_sections[arg1]
|
|
|
|
sys.argv[1:2] = section.includes
|
|
|
|
elif arg1.startswith('IPython.') and arg1[8:] in test_sections:
|
|
|
|
section = test_sections[arg1[8:]]
|
2013-09-10 01:48:29 +08:00
|
|
|
sys.argv[1:2] = section.includes
|
|
|
|
else:
|
|
|
|
section = TestSection(arg1, includes=[arg1])
|
|
|
|
|
2008-08-24 14:37:40 +08:00
|
|
|
|
2010-01-17 06:43:41 +08:00
|
|
|
argv = sys.argv + [ '--detailed-errors', # extra info in tracebacks
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2010-01-10 08:30:59 +08:00
|
|
|
'--with-ipdoctest',
|
|
|
|
'--ipdoctest-tests','--ipdoctest-extension=txt',
|
2011-10-04 22:14:41 +08:00
|
|
|
|
2008-11-09 13:54:34 +08:00
|
|
|
# We add --exe because of setuptools' imbecility (it
|
|
|
|
# blindly does chmod +x on ALL files). Nose does the
|
|
|
|
# right thing and it tries to avoid executables,
|
|
|
|
# setuptools unfortunately forces our hand here. This
|
|
|
|
# has been discussed on the distutils list and the
|
|
|
|
# setuptools devs refuse to fix this problem!
|
|
|
|
'--exe',
|
|
|
|
]
|
2012-08-11 13:14:53 +08:00
|
|
|
if '-a' not in argv and '-A' not in argv:
|
|
|
|
argv = argv + ['-a', '!crash']
|
2008-08-24 14:37:40 +08:00
|
|
|
|
2010-01-18 05:13:21 +08:00
|
|
|
if nose.__version__ >= '0.11':
|
|
|
|
# I don't fully understand why we need this one, but depending on what
|
|
|
|
# directory the test suite is run from, if we don't give it, 0 tests
|
|
|
|
# get run. Specifically, if the test suite is run from the source dir
|
|
|
|
# with an argument (like 'iptest.py IPython.core', 0 tests are run,
|
|
|
|
# even if the same call done in this directory works fine). It appears
|
|
|
|
# that if the requested package is in the current dir, nose bails early
|
|
|
|
# by default. Since it's otherwise harmless, leave it in by default
|
|
|
|
# for nose >= 0.11, though unfortunately nose 0.10 doesn't support it.
|
|
|
|
argv.append('--traverse-namespace')
|
2008-08-24 14:37:40 +08:00
|
|
|
|
2011-08-07 10:54:42 +08:00
|
|
|
# use our plugin for doctesting. It will remove the standard doctest plugin
|
|
|
|
# if it finds it enabled
|
2013-09-06 06:37:30 +08:00
|
|
|
plugins = [ExclusionPlugin(section.excludes), IPythonDoctest(), KnownFailure()]
|
|
|
|
|
|
|
|
# Use working directory set by parent process (see iptestcontroller)
|
|
|
|
if 'IPTEST_WORKING_DIR' in os.environ:
|
|
|
|
os.chdir(os.environ['IPTEST_WORKING_DIR'])
|
2012-09-27 07:23:54 +08:00
|
|
|
|
|
|
|
# We need a global ipython running in this process, but the special
|
|
|
|
# in-process group spawns its own IPython kernels, so for *that* group we
|
|
|
|
# must avoid also opening the global one (otherwise there's a conflict of
|
|
|
|
# singletons). Ultimately the solution to this problem is to refactor our
|
|
|
|
# assumptions about what needs to be a singleton and what doesn't (app
|
|
|
|
# objects should, individual shells shouldn't). But for now, this
|
|
|
|
# workaround allows the test suite for the inprocess module to complete.
|
2013-09-10 01:48:29 +08:00
|
|
|
if 'kernel.inprocess' not in section.name:
|
2013-09-07 02:02:41 +08:00
|
|
|
from IPython.testing import globalipapp
|
2012-09-27 07:23:54 +08:00
|
|
|
globalipapp.start_ipython()
|
|
|
|
|
2010-01-10 08:30:59 +08:00
|
|
|
# Now nose can run
|
2011-08-07 10:54:42 +08:00
|
|
|
TestProgram(argv=argv, addplugins=plugins)
|
2009-04-25 01:12:50 +08:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2013-09-05 06:58:51 +08:00
|
|
|
run_iptest()
|
2013-09-07 02:02:41 +08:00
|
|
|
|