Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / test.py @ 01413001

History | View | Annotate | Download (13.4 kB)

1 2fde8651 Stavros Sachtouris
# Copyright 2013 GRNET S.A. All rights reserved.
2 2fde8651 Stavros Sachtouris
#
3 2fde8651 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 2fde8651 Stavros Sachtouris
# without modification, are permitted provided that the following
5 2fde8651 Stavros Sachtouris
# conditions are met:
6 2fde8651 Stavros Sachtouris
#
7 2fde8651 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 2fde8651 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 2fde8651 Stavros Sachtouris
#      disclaimer.
10 2fde8651 Stavros Sachtouris
#
11 2fde8651 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 2fde8651 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 2fde8651 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 2fde8651 Stavros Sachtouris
#      provided with the distribution.
15 2fde8651 Stavros Sachtouris
#
16 2fde8651 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 2fde8651 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 2fde8651 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 2fde8651 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 2fde8651 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 2fde8651 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 2fde8651 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 2fde8651 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 2fde8651 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 2fde8651 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 2fde8651 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 2fde8651 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 2fde8651 Stavros Sachtouris
#
29 2fde8651 Stavros Sachtouris
# The views and conclusions contained in the software and
30 2fde8651 Stavros Sachtouris
# documentation are those of the authors and should not be
31 2fde8651 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 2fde8651 Stavros Sachtouris
# or implied, of GRNET S.A.
33 2fde8651 Stavros Sachtouris
34 2fde8651 Stavros Sachtouris
from unittest import makeSuite, TestSuite, TextTestRunner, TestCase
35 2fde8651 Stavros Sachtouris
from inspect import getmembers, isclass
36 98093aac Stavros Sachtouris
from tempfile import NamedTemporaryFile
37 4769da6b Stavros Sachtouris
from mock import patch, call
38 4769da6b Stavros Sachtouris
from itertools import product
39 2fde8651 Stavros Sachtouris
40 0962adb7 Stavros Sachtouris
from kamaki.cli.command_tree.test import Command, CommandTree
41 3a5b1ceb Stavros Sachtouris
from kamaki.cli.argument.test import (
42 3a5b1ceb Stavros Sachtouris
    Argument, ConfigArgument, RuntimeConfigArgument, FlagArgument,
43 8d427cb9 Stavros Sachtouris
    ValueArgument, IntArgument, DateArgument, VersionArgument,
44 ca5528f1 Stavros Sachtouris
    RepeatableArgument, KeyValueArgument, ProgressBarArgument,
45 ca5528f1 Stavros Sachtouris
    ArgumentParseManager)
46 b3cb58c2 Stavros Sachtouris
from kamaki.cli.utils.test import UtilsMethods
47 2fde8651 Stavros Sachtouris
48 2fde8651 Stavros Sachtouris
49 98093aac Stavros Sachtouris
class History(TestCase):
50 98093aac Stavros Sachtouris
51 98093aac Stavros Sachtouris
    def setUp(self):
52 98093aac Stavros Sachtouris
        from kamaki.cli.history import History as HClass
53 98093aac Stavros Sachtouris
        self.HCLASS = HClass
54 98093aac Stavros Sachtouris
        self.file = NamedTemporaryFile()
55 98093aac Stavros Sachtouris
56 98093aac Stavros Sachtouris
    def tearDown(self):
57 98093aac Stavros Sachtouris
        self.file.close()
58 98093aac Stavros Sachtouris
59 98093aac Stavros Sachtouris
    def test__match(self):
60 98093aac Stavros Sachtouris
        self.assertRaises(AttributeError, self.HCLASS._match, 'ok', 42)
61 98093aac Stavros Sachtouris
        self.assertRaises(TypeError, self.HCLASS._match, 2.71, 'ok')
62 98093aac Stavros Sachtouris
        for args, expected in (
63 98093aac Stavros Sachtouris
                (('XXX', None), True),
64 98093aac Stavros Sachtouris
                ((None, None), True),
65 98093aac Stavros Sachtouris
                (('this line has some terms', 'some terms'), True),
66 98093aac Stavros Sachtouris
                (('this line has some terms', 'some bad terms'), False),
67 98093aac Stavros Sachtouris
                (('small line', 'not so small line terms'), False),
68 98093aac Stavros Sachtouris
                ((['line', 'with', 'some', 'terms'], 'some terms'), True),
69 98093aac Stavros Sachtouris
                ((['line', 'with', 'some terms'], 'some terms'), False)):
70 98093aac Stavros Sachtouris
            self.assertEqual(self.HCLASS._match(*args), expected)
71 98093aac Stavros Sachtouris
72 98093aac Stavros Sachtouris
    def test_get(self):
73 98093aac Stavros Sachtouris
        history = self.HCLASS(self.file.name)
74 98093aac Stavros Sachtouris
        self.assertEqual(history.get(), [])
75 98093aac Stavros Sachtouris
76 98093aac Stavros Sachtouris
        sample_history = (
77 98093aac Stavros Sachtouris
            'kamaki history show\n',
78 98093aac Stavros Sachtouris
            'kamaki file list\n',
79 98093aac Stavros Sachtouris
            'kamaki touch pithos:f1\n',
80 98093aac Stavros Sachtouris
            'kamaki file info pithos:f1\n')
81 98093aac Stavros Sachtouris
        self.file.write(''.join(sample_history))
82 98093aac Stavros Sachtouris
        self.file.flush()
83 98093aac Stavros Sachtouris
84 98093aac Stavros Sachtouris
        expected = ['%s.  \t%s' % (
85 98093aac Stavros Sachtouris
            i + 1, event) for i, event in enumerate(sample_history)]
86 98093aac Stavros Sachtouris
        self.assertEqual(history.get(), expected)
87 98093aac Stavros Sachtouris
        self.assertEqual(history.get('kamaki'), expected)
88 98093aac Stavros Sachtouris
        self.assertEqual(history.get('file kamaki'), expected[1::2])
89 98093aac Stavros Sachtouris
        self.assertEqual(history.get('pithos:f1'), expected[2:])
90 98093aac Stavros Sachtouris
        self.assertEqual(history.get('touch pithos:f1'), expected[2:3])
91 98093aac Stavros Sachtouris
92 98093aac Stavros Sachtouris
        for limit in range(len(sample_history)):
93 98093aac Stavros Sachtouris
            self.assertEqual(history.get(limit=limit), expected[-limit:])
94 98093aac Stavros Sachtouris
            self.assertEqual(
95 98093aac Stavros Sachtouris
                history.get('kamaki', limit=limit), expected[-limit:])
96 98093aac Stavros Sachtouris
97 98093aac Stavros Sachtouris
    def test_add(self):
98 98093aac Stavros Sachtouris
        history = self.HCLASS(self.file.name)
99 98093aac Stavros Sachtouris
        some_strings = ('a brick', 'two bricks', 'another brick', 'A wall!')
100 98093aac Stavros Sachtouris
        for i, line in enumerate(some_strings):
101 98093aac Stavros Sachtouris
            history.add(line)
102 98093aac Stavros Sachtouris
            self.file.seek(0)
103 98093aac Stavros Sachtouris
            self.assertEqual(
104 98093aac Stavros Sachtouris
                self.file.read(), '\n'.join(some_strings[:(i + 1)]) + '\n')
105 98093aac Stavros Sachtouris
106 98093aac Stavros Sachtouris
    def test_clean(self):
107 98093aac Stavros Sachtouris
        content = 'a brick\ntwo bricks\nanother brick\nA wall!\n'
108 98093aac Stavros Sachtouris
        self.file.write(content)
109 98093aac Stavros Sachtouris
        self.file.flush()
110 98093aac Stavros Sachtouris
        self.file.seek(0)
111 98093aac Stavros Sachtouris
        self.assertEqual(self.file.read(), content)
112 98093aac Stavros Sachtouris
        history = self.HCLASS(self.file.name)
113 98093aac Stavros Sachtouris
        history.clean()
114 98093aac Stavros Sachtouris
        self.file.seek(0)
115 98093aac Stavros Sachtouris
        self.assertEqual(self.file.read(), '')
116 98093aac Stavros Sachtouris
117 98093aac Stavros Sachtouris
    def test_retrieve(self):
118 98093aac Stavros Sachtouris
        sample_history = (
119 98093aac Stavros Sachtouris
            'kamaki history show\n',
120 98093aac Stavros Sachtouris
            'kamaki file list\n',
121 98093aac Stavros Sachtouris
            'kamaki touch pithos:f1\n',
122 98093aac Stavros Sachtouris
            'kamaki file info pithos:f1\n',
123 98093aac Stavros Sachtouris
            'current / last command is always excluded')
124 98093aac Stavros Sachtouris
        self.file.write(''.join(sample_history))
125 98093aac Stavros Sachtouris
        self.file.flush()
126 98093aac Stavros Sachtouris
127 98093aac Stavros Sachtouris
        history = self.HCLASS(self.file.name)
128 98093aac Stavros Sachtouris
        self.assertRaises(ValueError, history.retrieve, 'must be number')
129 98093aac Stavros Sachtouris
        self.assertRaises(TypeError, history.retrieve, [1, 2, 3])
130 98093aac Stavros Sachtouris
131 98093aac Stavros Sachtouris
        for i in (0, len(sample_history), -len(sample_history)):
132 98093aac Stavros Sachtouris
            self.assertEqual(history.retrieve(i), None)
133 98093aac Stavros Sachtouris
        for i in range(1, len(sample_history)):
134 98093aac Stavros Sachtouris
            self.assertEqual(history.retrieve(i), sample_history[i - 1])
135 98093aac Stavros Sachtouris
            self.assertEqual(history.retrieve(- i), sample_history[- i - 1])
136 98093aac Stavros Sachtouris
137 98093aac Stavros Sachtouris
138 4769da6b Stavros Sachtouris
class LoggerMethods(TestCase):
139 4769da6b Stavros Sachtouris
140 4769da6b Stavros Sachtouris
    class PseudoLogger(object):
141 4769da6b Stavros Sachtouris
        level = 'some level'
142 4769da6b Stavros Sachtouris
        _setLevel_calls = []
143 4769da6b Stavros Sachtouris
        _addHandler_calls = []
144 4769da6b Stavros Sachtouris
145 4769da6b Stavros Sachtouris
        def setLevel(self, *args):
146 4769da6b Stavros Sachtouris
            self._setLevel_calls.append(args)
147 4769da6b Stavros Sachtouris
148 4769da6b Stavros Sachtouris
        def addHandler(self, *args):
149 4769da6b Stavros Sachtouris
            self._addHandler_calls.append(args)
150 4769da6b Stavros Sachtouris
151 4769da6b Stavros Sachtouris
    class PseudoHandler(object):
152 4769da6b Stavros Sachtouris
        _setFormatter_calls = []
153 4769da6b Stavros Sachtouris
154 4769da6b Stavros Sachtouris
        def setFormatter(self, *args):
155 4769da6b Stavros Sachtouris
            self._setFormatter_calls.append(args)
156 4769da6b Stavros Sachtouris
157 4769da6b Stavros Sachtouris
    def setUp(self):
158 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import LOG_FILE, _blacklist
159 4769da6b Stavros Sachtouris
        self.LF, self.BL = list(LOG_FILE), dict(_blacklist)
160 4769da6b Stavros Sachtouris
161 4769da6b Stavros Sachtouris
    def tearDown(self):
162 4769da6b Stavros Sachtouris
        self.PseudoLogger._setLevel_calls = []
163 4769da6b Stavros Sachtouris
        self.PseudoLogger._addHandler_calls = []
164 4769da6b Stavros Sachtouris
        self.PseudoLogger._setFormatter_calls = []
165 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import LOG_FILE, _blacklist
166 4769da6b Stavros Sachtouris
        for e in LOG_FILE:
167 4769da6b Stavros Sachtouris
            LOG_FILE.pop()
168 4769da6b Stavros Sachtouris
        for e in self.LF:
169 4769da6b Stavros Sachtouris
            LOG_FILE.append(e)
170 4769da6b Stavros Sachtouris
        _blacklist.clear()
171 4769da6b Stavros Sachtouris
        _blacklist.update(self.BL)
172 4769da6b Stavros Sachtouris
173 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.logging.getLogger', return_value=PseudoLogger())
174 4769da6b Stavros Sachtouris
    def test_deactivate(self, GL):
175 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import deactivate, _blacklist
176 4769da6b Stavros Sachtouris
        self.assertEqual(_blacklist, {})
177 4769da6b Stavros Sachtouris
        deactivate('some logger')
178 4769da6b Stavros Sachtouris
        GL.assert_called_once_with('some logger')
179 4769da6b Stavros Sachtouris
        self.assertEqual(
180 4769da6b Stavros Sachtouris
            _blacklist.get('some logger', None), self.PseudoLogger.level)
181 4769da6b Stavros Sachtouris
        from logging import CRITICAL
182 4769da6b Stavros Sachtouris
        self.assertEqual(self.PseudoLogger._setLevel_calls[-1], (CRITICAL, ))
183 4769da6b Stavros Sachtouris
184 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.logging.getLogger', return_value=PseudoLogger())
185 4769da6b Stavros Sachtouris
    def test_activate(self, GL):
186 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import activate
187 4769da6b Stavros Sachtouris
        activate('another logger')
188 4769da6b Stavros Sachtouris
        GL.assert_called_once_with('another logger')
189 4769da6b Stavros Sachtouris
        self.assertEqual(
190 4769da6b Stavros Sachtouris
            self.PseudoLogger._setLevel_calls[-1], (self.PseudoLogger.level, ))
191 4769da6b Stavros Sachtouris
192 4769da6b Stavros Sachtouris
    def test_get_log_filename(self):
193 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import get_log_filename, LOG_FILE
194 4769da6b Stavros Sachtouris
        f = NamedTemporaryFile()
195 4769da6b Stavros Sachtouris
        for e in LOG_FILE:
196 4769da6b Stavros Sachtouris
            LOG_FILE.pop()
197 4769da6b Stavros Sachtouris
        LOG_FILE.append(f.name)
198 4769da6b Stavros Sachtouris
        self.assertEqual(get_log_filename(), f.name)
199 4769da6b Stavros Sachtouris
        LOG_FILE.pop()
200 4769da6b Stavros Sachtouris
        LOG_FILE.append(2 * f.name)
201 4769da6b Stavros Sachtouris
        print('\n  Should print error msg here: ')
202 4769da6b Stavros Sachtouris
        self.assertEqual(get_log_filename(), None)
203 4769da6b Stavros Sachtouris
204 4769da6b Stavros Sachtouris
    def test_set_log_filename(self):
205 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import set_log_filename, LOG_FILE
206 4769da6b Stavros Sachtouris
        for n in ('some name', 'some other name'):
207 4769da6b Stavros Sachtouris
            set_log_filename(n)
208 4769da6b Stavros Sachtouris
            self.assertEqual(LOG_FILE[0], n)
209 4769da6b Stavros Sachtouris
210 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.get_logger', return_value=PseudoLogger())
211 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.logging.Formatter', return_value='f0rm4t')
212 4769da6b Stavros Sachtouris
    @patch(
213 4769da6b Stavros Sachtouris
        'kamaki.cli.logger.logging.StreamHandler',
214 4769da6b Stavros Sachtouris
        return_value=PseudoHandler())
215 4769da6b Stavros Sachtouris
    @patch(
216 4769da6b Stavros Sachtouris
        'kamaki.cli.logger.logging.FileHandler',
217 4769da6b Stavros Sachtouris
        return_value=PseudoHandler())
218 4769da6b Stavros Sachtouris
    def test__add_logger(self, FH, SH, F, GL):
219 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import _add_logger
220 4769da6b Stavros Sachtouris
        from logging import DEBUG
221 4769da6b Stavros Sachtouris
        stdf, cnt = '%(name)s\n %(message)s', 0
222 4769da6b Stavros Sachtouris
        for name, level, filename, fmt in product(
223 4769da6b Stavros Sachtouris
                ('my logger', ),
224 4769da6b Stavros Sachtouris
                ('my level', None),
225 4769da6b Stavros Sachtouris
                ('my filename', None),
226 4769da6b Stavros Sachtouris
                ('my fmt', None)):
227 4769da6b Stavros Sachtouris
            log = _add_logger(name, level, filename, fmt)
228 4769da6b Stavros Sachtouris
            self.assertTrue(isinstance(log, self.PseudoLogger))
229 4769da6b Stavros Sachtouris
            self.assertEqual(GL.mock_calls[-1], call(name))
230 4769da6b Stavros Sachtouris
            if filename:
231 4769da6b Stavros Sachtouris
                self.assertEqual(FH.mock_calls[-1], call(filename))
232 4769da6b Stavros Sachtouris
            else:
233 4769da6b Stavros Sachtouris
                self.assertEqual(SH.mock_calls[-1], call())
234 4769da6b Stavros Sachtouris
            self.assertEqual(F.mock_calls[-1], call(fmt or stdf))
235 4769da6b Stavros Sachtouris
            self.assertEqual(
236 4769da6b Stavros Sachtouris
                self.PseudoHandler._setFormatter_calls[-1], ('f0rm4t', ))
237 4769da6b Stavros Sachtouris
            cnt += 1
238 4769da6b Stavros Sachtouris
            self.assertEqual(len(self.PseudoLogger._addHandler_calls), cnt)
239 4769da6b Stavros Sachtouris
            h = self.PseudoLogger._addHandler_calls[-1]
240 4769da6b Stavros Sachtouris
            self.assertTrue(isinstance(h[0], self.PseudoHandler))
241 4769da6b Stavros Sachtouris
            l = self.PseudoLogger._setLevel_calls[-1]
242 4769da6b Stavros Sachtouris
            self.assertEqual(l, (level or DEBUG, ))
243 4769da6b Stavros Sachtouris
244 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.get_log_filename', return_value='my log fname')
245 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.get_logger', return_value='my get logger ret')
246 4769da6b Stavros Sachtouris
    def test_add_file_logger(self, GL, GLF):
247 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import add_file_logger
248 4769da6b Stavros Sachtouris
        with patch('kamaki.cli.logger._add_logger', return_value='AL') as AL:
249 4769da6b Stavros Sachtouris
            GLFcount = GLF.call_count
250 4769da6b Stavros Sachtouris
            for name, level, filename in product(
251 4769da6b Stavros Sachtouris
                    ('my name'), ('my level', None), ('my filename', None)):
252 4769da6b Stavros Sachtouris
                self.assertEqual(add_file_logger(name, level, filename), 'AL')
253 4769da6b Stavros Sachtouris
                self.assertEqual(AL.mock_calls[-1], call(
254 4769da6b Stavros Sachtouris
                    name, level, filename or 'my log fname',
255 4769da6b Stavros Sachtouris
                    fmt='%(name)s(%(levelname)s) %(asctime)s\n\t%(message)s'))
256 4769da6b Stavros Sachtouris
                if filename:
257 4769da6b Stavros Sachtouris
                    self.assertEqual(GLFcount, GLF.call_count)
258 4769da6b Stavros Sachtouris
                else:
259 4769da6b Stavros Sachtouris
                    GLFcount = GLF.call_count
260 4769da6b Stavros Sachtouris
                    self.assertEqual(GLF.mock_calls[-1], call())
261 4769da6b Stavros Sachtouris
        with patch('kamaki.cli.logger._add_logger', side_effect=Exception):
262 4769da6b Stavros Sachtouris
            self.assertEqual(add_file_logger('X'), 'my get logger ret')
263 4769da6b Stavros Sachtouris
            GL.assert_called_once_with('X')
264 4769da6b Stavros Sachtouris
265 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.get_logger', return_value='my get logger ret')
266 4769da6b Stavros Sachtouris
    def test_add_stream_logger(self, GL):
267 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import add_stream_logger
268 4769da6b Stavros Sachtouris
        with patch('kamaki.cli.logger._add_logger', return_value='AL') as AL:
269 4769da6b Stavros Sachtouris
            for name, level, fmt in product(
270 4769da6b Stavros Sachtouris
                    ('my name'), ('my level', None), ('my fmt', None)):
271 4769da6b Stavros Sachtouris
                self.assertEqual(add_stream_logger(name, level, fmt), 'AL')
272 4769da6b Stavros Sachtouris
                self.assertEqual(AL.mock_calls[-1], call(name, level, fmt=fmt))
273 4769da6b Stavros Sachtouris
        with patch('kamaki.cli.logger._add_logger', side_effect=Exception):
274 4769da6b Stavros Sachtouris
            self.assertEqual(add_stream_logger('X'), 'my get logger ret')
275 4769da6b Stavros Sachtouris
            GL.assert_called_once_with('X')
276 4769da6b Stavros Sachtouris
277 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.logging.getLogger', return_value=PseudoLogger())
278 4769da6b Stavros Sachtouris
    def test_get_logger(self, GL):
279 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import get_logger
280 4769da6b Stavros Sachtouris
        get_logger('my logger name')
281 4769da6b Stavros Sachtouris
        GL.assert_called_once_with('my logger name')
282 4769da6b Stavros Sachtouris
283 4769da6b Stavros Sachtouris
284 2fde8651 Stavros Sachtouris
#  TestCase auxiliary methods
285 2fde8651 Stavros Sachtouris
286 2fde8651 Stavros Sachtouris
def runTestCase(cls, test_name, args=[], failure_collector=[]):
287 2fde8651 Stavros Sachtouris
    """
288 2fde8651 Stavros Sachtouris
    :param cls: (TestCase) a set of Tests
289 2fde8651 Stavros Sachtouris

290 2fde8651 Stavros Sachtouris
    :param test_name: (str)
291 2fde8651 Stavros Sachtouris

292 2fde8651 Stavros Sachtouris
    :param args: (list) these are prefixed with test_ and used as params when
293 2fde8651 Stavros Sachtouris
        instantiating cls
294 2fde8651 Stavros Sachtouris

295 2fde8651 Stavros Sachtouris
    :param failure_collector: (list) collects info of test failures
296 2fde8651 Stavros Sachtouris

297 2fde8651 Stavros Sachtouris
    :returns: (int) total # of run tests
298 2fde8651 Stavros Sachtouris
    """
299 2fde8651 Stavros Sachtouris
    suite = TestSuite()
300 2fde8651 Stavros Sachtouris
    if args:
301 2fde8651 Stavros Sachtouris
        suite.addTest(cls('_'.join(['test'] + args)))
302 2fde8651 Stavros Sachtouris
    else:
303 2fde8651 Stavros Sachtouris
        suite.addTest(makeSuite(cls))
304 2fde8651 Stavros Sachtouris
    print('* Test * %s *' % test_name)
305 2fde8651 Stavros Sachtouris
    r = TextTestRunner(verbosity=2).run(suite)
306 2fde8651 Stavros Sachtouris
    failure_collector += r.failures
307 2fde8651 Stavros Sachtouris
    return r.testsRun
308 2fde8651 Stavros Sachtouris
309 2fde8651 Stavros Sachtouris
310 2fde8651 Stavros Sachtouris
def get_test_classes(module=__import__(__name__), name=''):
311 2fde8651 Stavros Sachtouris
    module_stack = [module]
312 2fde8651 Stavros Sachtouris
    while module_stack:
313 2fde8651 Stavros Sachtouris
        module = module_stack[-1]
314 2fde8651 Stavros Sachtouris
        module_stack = module_stack[:-1]
315 2fde8651 Stavros Sachtouris
        for objname, obj in getmembers(module):
316 2fde8651 Stavros Sachtouris
            if (objname == name or not name):
317 2fde8651 Stavros Sachtouris
                if isclass(obj) and objname != 'TestCase' and (
318 2fde8651 Stavros Sachtouris
                        issubclass(obj, TestCase)):
319 2fde8651 Stavros Sachtouris
                    yield (obj, objname)
320 2fde8651 Stavros Sachtouris
321 2fde8651 Stavros Sachtouris
322 2fde8651 Stavros Sachtouris
def main(argv):
323 2fde8651 Stavros Sachtouris
    found = False
324 2fde8651 Stavros Sachtouris
    failure_collector = list()
325 2fde8651 Stavros Sachtouris
    num_of_tests = 0
326 2fde8651 Stavros Sachtouris
    for cls, name in get_test_classes(name=argv[1] if len(argv) > 1 else ''):
327 2fde8651 Stavros Sachtouris
        found = True
328 2fde8651 Stavros Sachtouris
        num_of_tests += runTestCase(cls, name, argv[2:], failure_collector)
329 2fde8651 Stavros Sachtouris
    if not found:
330 2fde8651 Stavros Sachtouris
        print('Test "%s" not found' % ' '.join(argv[1:]))
331 2fde8651 Stavros Sachtouris
    else:
332 2fde8651 Stavros Sachtouris
        for i, failure in enumerate(failure_collector):
333 2fde8651 Stavros Sachtouris
            print('Failure %s: ' % (i + 1))
334 2fde8651 Stavros Sachtouris
            for field in failure:
335 2fde8651 Stavros Sachtouris
                print('\t%s' % field)
336 2fde8651 Stavros Sachtouris
        print('\nTotal tests run: %s' % num_of_tests)
337 2fde8651 Stavros Sachtouris
        print('Total failures: %s' % len(failure_collector))
338 2fde8651 Stavros Sachtouris
339 2fde8651 Stavros Sachtouris
340 2fde8651 Stavros Sachtouris
if __name__ == '__main__':
341 2fde8651 Stavros Sachtouris
    from sys import argv
342 2fde8651 Stavros Sachtouris
    main(argv)