Show More
@@ -0,0 +1,132 b'' | |||
|
1 | # encoding: utf-8 | |
|
2 | """ | |
|
3 | Testing related decorators for use with twisted.trial. | |
|
4 | ||
|
5 | The decorators in this files are designed to follow the same API as those | |
|
6 | in the decorators module (in this same directory). But they can be used | |
|
7 | with twisted.trial | |
|
8 | """ | |
|
9 | ||
|
10 | #----------------------------------------------------------------------------- | |
|
11 | # Copyright (C) 2008-2009 The IPython Development Team | |
|
12 | # | |
|
13 | # Distributed under the terms of the BSD License. The full license is in | |
|
14 | # the file COPYING, distributed as part of this software. | |
|
15 | #----------------------------------------------------------------------------- | |
|
16 | ||
|
17 | #----------------------------------------------------------------------------- | |
|
18 | # Imports | |
|
19 | #----------------------------------------------------------------------------- | |
|
20 | ||
|
21 | import os | |
|
22 | import sys | |
|
23 | ||
|
24 | from IPython.testing.decorators import make_label_dec | |
|
25 | ||
|
26 | #----------------------------------------------------------------------------- | |
|
27 | # Testing decorators | |
|
28 | #----------------------------------------------------------------------------- | |
|
29 | ||
|
30 | ||
|
31 | def skipif(skip_condition, msg=None): | |
|
32 | """Create a decorator that marks a test function for skipping. | |
|
33 | ||
|
34 | The is a decorator factory that returns a decorator that will | |
|
35 | conditionally skip a test based on the value of skip_condition. The | |
|
36 | skip_condition argument can either be a boolean or a callable that returns | |
|
37 | a boolean. | |
|
38 | ||
|
39 | Parameters | |
|
40 | ---------- | |
|
41 | skip_condition : boolean or callable | |
|
42 | If this evaluates to True, the test is skipped. | |
|
43 | msg : str | |
|
44 | The message to print if the test is skipped. | |
|
45 | ||
|
46 | Returns | |
|
47 | ------- | |
|
48 | decorator : function | |
|
49 | The decorator function that can be applied to the test function. | |
|
50 | """ | |
|
51 | ||
|
52 | def skip_decorator(f): | |
|
53 | ||
|
54 | # Allow for both boolean or callable skip conditions. | |
|
55 | if callable(skip_condition): | |
|
56 | skip_val = lambda : skip_condition() | |
|
57 | else: | |
|
58 | skip_val = lambda : skip_condition | |
|
59 | ||
|
60 | if msg is None: | |
|
61 | out = 'Test skipped due to test condition.' | |
|
62 | else: | |
|
63 | out = msg | |
|
64 | final_msg = "Skipping test: %s. %s" % (f.__name__,out) | |
|
65 | ||
|
66 | if skip_val(): | |
|
67 | f.skip = final_msg | |
|
68 | ||
|
69 | return f | |
|
70 | return skip_decorator | |
|
71 | ||
|
72 | ||
|
73 | def skip(msg=None): | |
|
74 | """Create a decorator that marks a test function for skipping. | |
|
75 | ||
|
76 | This is a decorator factory that returns a decorator that will cause | |
|
77 | tests to be skipped. | |
|
78 | ||
|
79 | Parameters | |
|
80 | ---------- | |
|
81 | msg : str | |
|
82 | Optional message to be added. | |
|
83 | ||
|
84 | Returns | |
|
85 | ------- | |
|
86 | decorator : function | |
|
87 | Decorator, which, when applied to a function, sets the skip | |
|
88 | attribute of the function causing `twisted.trial` to skip it. | |
|
89 | """ | |
|
90 | ||
|
91 | return skipif(True,msg) | |
|
92 | ||
|
93 | ||
|
94 | def numpy_not_available(): | |
|
95 | """Can numpy be imported? Returns true if numpy does NOT import. | |
|
96 | ||
|
97 | This is used to make a decorator to skip tests that require numpy to be | |
|
98 | available, but delay the 'import numpy' to test execution time. | |
|
99 | """ | |
|
100 | try: | |
|
101 | import numpy | |
|
102 | np_not_avail = False | |
|
103 | except ImportError: | |
|
104 | np_not_avail = True | |
|
105 | ||
|
106 | return np_not_avail | |
|
107 | ||
|
108 | #----------------------------------------------------------------------------- | |
|
109 | # Decorators for public use | |
|
110 | #----------------------------------------------------------------------------- | |
|
111 | ||
|
112 | # Decorators to skip certain tests on specific platforms. | |
|
113 | skip_win32 = skipif(sys.platform == 'win32', | |
|
114 | "This test does not run under Windows") | |
|
115 | skip_linux = skipif(sys.platform == 'linux2', | |
|
116 | "This test does not run under Linux") | |
|
117 | skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X") | |
|
118 | ||
|
119 | # Decorators to skip tests if not on specific platforms. | |
|
120 | skip_if_not_win32 = skipif(sys.platform != 'win32', | |
|
121 | "This test only runs under Windows") | |
|
122 | skip_if_not_linux = skipif(sys.platform != 'linux2', | |
|
123 | "This test only runs under Linux") | |
|
124 | skip_if_not_osx = skipif(sys.platform != 'darwin', | |
|
125 | "This test only runs under OSX") | |
|
126 | ||
|
127 | # Other skip decorators | |
|
128 | skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy") | |
|
129 | ||
|
130 | skipknownfailure = skip('This test is known to fail') | |
|
131 | ||
|
132 |
@@ -22,15 +22,15 b' import sys' | |||
|
22 | 22 | |
|
23 | 23 | from twisted.trial import unittest |
|
24 | 24 | |
|
25 | from IPython.testing import decorators_trial as dec | |
|
26 | ||
|
25 | 27 | #----------------------------------------------------------------------------- |
|
26 | 28 | # Tests |
|
27 | 29 | #----------------------------------------------------------------------------- |
|
28 | 30 | |
|
29 | 31 | class TestRedirector(unittest.TestCase): |
|
30 | 32 | |
|
31 | if sys.platform == 'win32': | |
|
32 | skip = True | |
|
33 | ||
|
33 | @dec.skip_win32 | |
|
34 | 34 | def test_redirector(self): |
|
35 | 35 | """Checks that the redirector can be used to do synchronous capture. |
|
36 | 36 | """ |
@@ -51,6 +51,7 b' class TestRedirector(unittest.TestCase):' | |||
|
51 | 51 | result2 = "".join("%ic\n%i\n" %(i, i) for i in range(10)) |
|
52 | 52 | self.assertEquals(result1, result2) |
|
53 | 53 | |
|
54 | @dec.skip_win32 | |
|
54 | 55 | def test_redirector_output_trap(self): |
|
55 | 56 | """Check the greedy trapping behavior of the traps. |
|
56 | 57 |
@@ -49,9 +49,9 b' An IPython cluster consists of 1 controller and 1 or more engines.' | |||
|
49 | 49 | This command automates the startup of these processes using a wide |
|
50 | 50 | range of startup methods (SSH, local processes, PBS, mpiexec, |
|
51 | 51 | Windows HPC Server 2008). To start a cluster with 4 engines on your |
|
52 |
local host simply do |
|
|
53 |
you will typically do |
|
|
54 |
configuration files, followed by |
|
|
52 | local host simply do 'ipcluster start -n 4'. For more complex usage | |
|
53 | you will typically do 'ipcluster create -p mycluster', then edit | |
|
54 | configuration files, followed by 'ipcluster start -p mycluster -n 4'. | |
|
55 | 55 | """ |
|
56 | 56 | |
|
57 | 57 | |
@@ -106,24 +106,42 b' class IPClusterAppConfigLoader(ClusterDirConfigLoader):' | |||
|
106 | 106 | title='ipcluster subcommands', |
|
107 | 107 | description= |
|
108 | 108 | """ipcluster has a variety of subcommands. The general way of |
|
109 |
running ipcluster is 'ipcluster <cmd> [options]' |
|
|
110 |
|
|
|
109 | running ipcluster is 'ipcluster <cmd> [options]'. To get help | |
|
110 | on a particular subcommand do 'ipcluster <cmd> -h'.""" | |
|
111 | # help="For more help, type 'ipcluster <cmd> -h'", | |
|
111 | 112 | ) |
|
112 | 113 | |
|
113 | 114 | # The "list" subcommand parser |
|
114 | 115 | parser_list = subparsers.add_parser( |
|
115 | 116 | 'list', |
|
116 | help='List all clusters in cwd and ipython_dir.', | |
|
117 | 117 | parents=[parent_parser1], |
|
118 | argument_default=SUPPRESS | |
|
118 | argument_default=SUPPRESS, | |
|
119 | help="List all clusters in cwd and ipython_dir.", | |
|
120 | description= | |
|
121 | """List all available clusters, by cluster directory, that can | |
|
122 | be found in the current working directly or in the ipython | |
|
123 | directory. Cluster directories are named using the convention | |
|
124 | 'cluster_<profile>'.""" | |
|
119 | 125 | ) |
|
120 | 126 | |
|
121 | 127 | # The "create" subcommand parser |
|
122 | 128 | parser_create = subparsers.add_parser( |
|
123 | 129 | 'create', |
|
124 | help='Create a new cluster directory.', | |
|
125 | 130 | parents=[parent_parser1, parent_parser2], |
|
126 | argument_default=SUPPRESS | |
|
131 | argument_default=SUPPRESS, | |
|
132 | help="Create a new cluster directory.", | |
|
133 | description= | |
|
134 | """Create an ipython cluster directory by its profile name or | |
|
135 | cluster directory path. Cluster directories contain | |
|
136 | configuration, log and security related files and are named | |
|
137 | using the convention 'cluster_<profile>'. By default they are | |
|
138 | located in your ipython directory. Once created, you will | |
|
139 | probably need to edit the configuration files in the cluster | |
|
140 | directory to configure your cluster. Most users will create a | |
|
141 | cluster directory by profile name, | |
|
142 | 'ipcluster create -p mycluster', which will put the directory | |
|
143 | in '<ipython_dir>/cluster_mycluster'. | |
|
144 | """ | |
|
127 | 145 | ) |
|
128 | 146 | paa = parser_create.add_argument |
|
129 | 147 | paa('--reset-config', |
@@ -135,9 +153,19 b' class IPClusterAppConfigLoader(ClusterDirConfigLoader):' | |||
|
135 | 153 | # The "start" subcommand parser |
|
136 | 154 | parser_start = subparsers.add_parser( |
|
137 | 155 | 'start', |
|
138 | help='Start a cluster.', | |
|
139 | 156 | parents=[parent_parser1, parent_parser2], |
|
140 | argument_default=SUPPRESS | |
|
157 | argument_default=SUPPRESS, | |
|
158 | help="Start a cluster.", | |
|
159 | description= | |
|
160 | """Start an ipython cluster by its profile name or cluster | |
|
161 | directory. Cluster directories contain configuration, log and | |
|
162 | security related files and are named using the convention | |
|
163 | 'cluster_<profile>' and should be creating using the 'start' | |
|
164 | subcommand of 'ipcluster'. If your cluster directory is in | |
|
165 | the cwd or the ipython directory, you can simply refer to it | |
|
166 | using its profile name, 'ipcluster start -n 4 -p <profile>`, | |
|
167 | otherwise use the '--cluster-dir' option. | |
|
168 | """ | |
|
141 | 169 | ) |
|
142 | 170 | paa = parser_start.add_argument |
|
143 | 171 | paa('-n', '--number', |
@@ -160,9 +188,17 b' class IPClusterAppConfigLoader(ClusterDirConfigLoader):' | |||
|
160 | 188 | # The "stop" subcommand parser |
|
161 | 189 | parser_stop = subparsers.add_parser( |
|
162 | 190 | 'stop', |
|
163 | help='Stop a cluster.', | |
|
164 | 191 | parents=[parent_parser1, parent_parser2], |
|
165 | argument_default=SUPPRESS | |
|
192 | argument_default=SUPPRESS, | |
|
193 | help="Stop a running cluster.", | |
|
194 | description= | |
|
195 | """Stop a running ipython cluster by its profile name or cluster | |
|
196 | directory. Cluster directories are named using the convention | |
|
197 | 'cluster_<profile>'. If your cluster directory is in | |
|
198 | the cwd or the ipython directory, you can simply refer to it | |
|
199 | using its profile name, 'ipcluster stop -p <profile>`, otherwise | |
|
200 | use the '--cluster-dir' option. | |
|
201 | """ | |
|
166 | 202 | ) |
|
167 | 203 | paa = parser_stop.add_argument |
|
168 | 204 | paa('--signal', |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # encoding: utf-8 |
|
2 | 2 | """ |
|
3 | Tests for decorators.py compatibility with Twisted.trial | |
|
3 | Tests for decorators_trial.py | |
|
4 | 4 | """ |
|
5 | 5 | |
|
6 | 6 | #----------------------------------------------------------------------------- |
@@ -14,24 +14,19 b' Tests for decorators.py compatibility with Twisted.trial' | |||
|
14 | 14 | # Imports |
|
15 | 15 | #----------------------------------------------------------------------------- |
|
16 | 16 | |
|
17 |
# Tell nose to skip this module |
|
|
17 | # Tell nose to skip this module | |
|
18 | 18 | __test__ = {} |
|
19 | 19 | |
|
20 | 20 | import os |
|
21 | 21 | import sys |
|
22 | 22 | |
|
23 | 23 | from twisted.trial import unittest |
|
24 | import IPython.testing.decorators as dec | |
|
24 | import IPython.testing.decorators_trial as dec | |
|
25 | 25 | |
|
26 | 26 | #----------------------------------------------------------------------------- |
|
27 | 27 | # Tests |
|
28 | 28 | #----------------------------------------------------------------------------- |
|
29 | 29 | |
|
30 | # Note: this code is identical to that in test_decorators, but that one uses | |
|
31 | # stdlib unittest, not the one from twisted, which we are using here. While | |
|
32 | # somewhat redundant, we want to check both with the stdlib and with twisted, | |
|
33 | # so the duplication is OK. | |
|
34 | ||
|
35 | 30 | class TestDecoratorsTrial(unittest.TestCase): |
|
36 | 31 | |
|
37 | 32 | @dec.skip() |
General Comments 0
You need to be logged in to leave comments.
Login now