From fe93ed2193010a1b2fd94d55b1aaca441f9d0201 2010-01-31 16:59:05 From: Brian Granger Date: 2010-01-31 16:59:05 Subject: [PATCH] Reverted decorators_trial.py and added command line docs. * Reverted :mod:`IPython.testing.decorators_trial.py` and everything that uses it. * Updated the command line usage information for ipcluster. --- diff --git a/IPython/kernel/core/tests/test_redirectors.py b/IPython/kernel/core/tests/test_redirectors.py index fe48371..cc54449 100644 --- a/IPython/kernel/core/tests/test_redirectors.py +++ b/IPython/kernel/core/tests/test_redirectors.py @@ -22,15 +22,15 @@ import sys from twisted.trial import unittest +from IPython.testing import decorators_trial as dec + #----------------------------------------------------------------------------- # Tests #----------------------------------------------------------------------------- class TestRedirector(unittest.TestCase): - if sys.platform == 'win32': - skip = True - + @dec.skip_win32 def test_redirector(self): """Checks that the redirector can be used to do synchronous capture. """ @@ -51,6 +51,7 @@ class TestRedirector(unittest.TestCase): result2 = "".join("%ic\n%i\n" %(i, i) for i in range(10)) self.assertEquals(result1, result2) + @dec.skip_win32 def test_redirector_output_trap(self): """Check the greedy trapping behavior of the traps. diff --git a/IPython/kernel/ipclusterapp.py b/IPython/kernel/ipclusterapp.py index 4d8cf5a..a19b415 100755 --- a/IPython/kernel/ipclusterapp.py +++ b/IPython/kernel/ipclusterapp.py @@ -49,9 +49,9 @@ An IPython cluster consists of 1 controller and 1 or more engines. This command automates the startup of these processes using a wide range of startup methods (SSH, local processes, PBS, mpiexec, Windows HPC Server 2008). To start a cluster with 4 engines on your -local host simply do "ipcluster start -n 4". For more complex usage -you will typically do "ipcluster create -p mycluster", then edit -configuration files, followed by "ipcluster start -p mycluster -n 4". +local host simply do 'ipcluster start -n 4'. For more complex usage +you will typically do 'ipcluster create -p mycluster', then edit +configuration files, followed by 'ipcluster start -p mycluster -n 4'. """ @@ -106,24 +106,42 @@ class IPClusterAppConfigLoader(ClusterDirConfigLoader): title='ipcluster subcommands', description= """ipcluster has a variety of subcommands. The general way of - running ipcluster is 'ipcluster [options]'""", - help="For more help, type 'ipcluster -h'" + running ipcluster is 'ipcluster [options]'. To get help + on a particular subcommand do 'ipcluster -h'.""" + # help="For more help, type 'ipcluster -h'", ) # The "list" subcommand parser parser_list = subparsers.add_parser( 'list', - help='List all clusters in cwd and ipython_dir.', parents=[parent_parser1], - argument_default=SUPPRESS + argument_default=SUPPRESS, + help="List all clusters in cwd and ipython_dir.", + description= + """List all available clusters, by cluster directory, that can + be found in the current working directly or in the ipython + directory. Cluster directories are named using the convention + 'cluster_'.""" ) # The "create" subcommand parser parser_create = subparsers.add_parser( 'create', - help='Create a new cluster directory.', parents=[parent_parser1, parent_parser2], - argument_default=SUPPRESS + argument_default=SUPPRESS, + help="Create a new cluster directory.", + description= + """Create an ipython cluster directory by its profile name or + cluster directory path. Cluster directories contain + configuration, log and security related files and are named + using the convention 'cluster_'. By default they are + located in your ipython directory. Once created, you will + probably need to edit the configuration files in the cluster + directory to configure your cluster. Most users will create a + cluster directory by profile name, + 'ipcluster create -p mycluster', which will put the directory + in '/cluster_mycluster'. + """ ) paa = parser_create.add_argument paa('--reset-config', @@ -135,9 +153,19 @@ class IPClusterAppConfigLoader(ClusterDirConfigLoader): # The "start" subcommand parser parser_start = subparsers.add_parser( 'start', - help='Start a cluster.', parents=[parent_parser1, parent_parser2], - argument_default=SUPPRESS + argument_default=SUPPRESS, + help="Start a cluster.", + description= + """Start an ipython cluster by its profile name or cluster + directory. Cluster directories contain configuration, log and + security related files and are named using the convention + 'cluster_' and should be creating using the 'start' + subcommand of 'ipcluster'. If your cluster directory is in + the cwd or the ipython directory, you can simply refer to it + using its profile name, 'ipcluster start -n 4 -p `, + otherwise use the '--cluster-dir' option. + """ ) paa = parser_start.add_argument paa('-n', '--number', @@ -160,9 +188,17 @@ class IPClusterAppConfigLoader(ClusterDirConfigLoader): # The "stop" subcommand parser parser_stop = subparsers.add_parser( 'stop', - help='Stop a cluster.', parents=[parent_parser1, parent_parser2], - argument_default=SUPPRESS + argument_default=SUPPRESS, + help="Stop a running cluster.", + description= + """Stop a running ipython cluster by its profile name or cluster + directory. Cluster directories are named using the convention + 'cluster_'. If your cluster directory is in + the cwd or the ipython directory, you can simply refer to it + using its profile name, 'ipcluster stop -p `, otherwise + use the '--cluster-dir' option. + """ ) paa = parser_stop.add_argument paa('--signal', diff --git a/IPython/testing/decorators_trial.py b/IPython/testing/decorators_trial.py new file mode 100644 index 0000000..231054b --- /dev/null +++ b/IPython/testing/decorators_trial.py @@ -0,0 +1,132 @@ +# encoding: utf-8 +""" +Testing related decorators for use with twisted.trial. + +The decorators in this files are designed to follow the same API as those +in the decorators module (in this same directory). But they can be used +with twisted.trial +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2009 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import sys + +from IPython.testing.decorators import make_label_dec + +#----------------------------------------------------------------------------- +# Testing decorators +#----------------------------------------------------------------------------- + + +def skipif(skip_condition, msg=None): + """Create a decorator that marks a test function for skipping. + + The is a decorator factory that returns a decorator that will + conditionally skip a test based on the value of skip_condition. The + skip_condition argument can either be a boolean or a callable that returns + a boolean. + + Parameters + ---------- + skip_condition : boolean or callable + If this evaluates to True, the test is skipped. + msg : str + The message to print if the test is skipped. + + Returns + ------- + decorator : function + The decorator function that can be applied to the test function. + """ + + def skip_decorator(f): + + # Allow for both boolean or callable skip conditions. + if callable(skip_condition): + skip_val = lambda : skip_condition() + else: + skip_val = lambda : skip_condition + + if msg is None: + out = 'Test skipped due to test condition.' + else: + out = msg + final_msg = "Skipping test: %s. %s" % (f.__name__,out) + + if skip_val(): + f.skip = final_msg + + return f + return skip_decorator + + +def skip(msg=None): + """Create a decorator that marks a test function for skipping. + + This is a decorator factory that returns a decorator that will cause + tests to be skipped. + + Parameters + ---------- + msg : str + Optional message to be added. + + Returns + ------- + decorator : function + Decorator, which, when applied to a function, sets the skip + attribute of the function causing `twisted.trial` to skip it. + """ + + return skipif(True,msg) + + +def numpy_not_available(): + """Can numpy be imported? Returns true if numpy does NOT import. + + This is used to make a decorator to skip tests that require numpy to be + available, but delay the 'import numpy' to test execution time. + """ + try: + import numpy + np_not_avail = False + except ImportError: + np_not_avail = True + + return np_not_avail + +#----------------------------------------------------------------------------- +# Decorators for public use +#----------------------------------------------------------------------------- + +# Decorators to skip certain tests on specific platforms. +skip_win32 = skipif(sys.platform == 'win32', + "This test does not run under Windows") +skip_linux = skipif(sys.platform == 'linux2', + "This test does not run under Linux") +skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X") + +# Decorators to skip tests if not on specific platforms. +skip_if_not_win32 = skipif(sys.platform != 'win32', + "This test only runs under Windows") +skip_if_not_linux = skipif(sys.platform != 'linux2', + "This test only runs under Linux") +skip_if_not_osx = skipif(sys.platform != 'darwin', + "This test only runs under OSX") + +# Other skip decorators +skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy") + +skipknownfailure = skip('This test is known to fail') + + diff --git a/IPython/testing/tests/test_decorators_trial.py b/IPython/testing/tests/test_decorators_trial.py index 427bede..b6157dc 100644 --- a/IPython/testing/tests/test_decorators_trial.py +++ b/IPython/testing/tests/test_decorators_trial.py @@ -1,6 +1,6 @@ # encoding: utf-8 """ -Tests for decorators.py compatibility with Twisted.trial +Tests for decorators_trial.py """ #----------------------------------------------------------------------------- @@ -14,24 +14,19 @@ Tests for decorators.py compatibility with Twisted.trial # Imports #----------------------------------------------------------------------------- -# Tell nose to skip this module, since this is for twisted only +# Tell nose to skip this module __test__ = {} import os import sys from twisted.trial import unittest -import IPython.testing.decorators as dec +import IPython.testing.decorators_trial as dec #----------------------------------------------------------------------------- # Tests #----------------------------------------------------------------------------- -# Note: this code is identical to that in test_decorators, but that one uses -# stdlib unittest, not the one from twisted, which we are using here. While -# somewhat redundant, we want to check both with the stdlib and with twisted, -# so the duplication is OK. - class TestDecoratorsTrial(unittest.TestCase): @dec.skip()