Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / test.py @ c79faeb5

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 631b7c35 Stavros Sachtouris
    KeyValueArgument, ProgressBarArgument, ArgumentParseManager)
45 b3cb58c2 Stavros Sachtouris
from kamaki.cli.utils.test import UtilsMethods
46 2fde8651 Stavros Sachtouris
47 2fde8651 Stavros Sachtouris
48 98093aac Stavros Sachtouris
class History(TestCase):
49 98093aac Stavros Sachtouris
50 98093aac Stavros Sachtouris
    def setUp(self):
51 98093aac Stavros Sachtouris
        from kamaki.cli.history import History as HClass
52 98093aac Stavros Sachtouris
        self.HCLASS = HClass
53 98093aac Stavros Sachtouris
        self.file = NamedTemporaryFile()
54 98093aac Stavros Sachtouris
55 98093aac Stavros Sachtouris
    def tearDown(self):
56 98093aac Stavros Sachtouris
        self.file.close()
57 98093aac Stavros Sachtouris
58 98093aac Stavros Sachtouris
    def test__match(self):
59 98093aac Stavros Sachtouris
        self.assertRaises(AttributeError, self.HCLASS._match, 'ok', 42)
60 98093aac Stavros Sachtouris
        self.assertRaises(TypeError, self.HCLASS._match, 2.71, 'ok')
61 98093aac Stavros Sachtouris
        for args, expected in (
62 98093aac Stavros Sachtouris
                (('XXX', None), True),
63 98093aac Stavros Sachtouris
                ((None, None), True),
64 98093aac Stavros Sachtouris
                (('this line has some terms', 'some terms'), True),
65 98093aac Stavros Sachtouris
                (('this line has some terms', 'some bad terms'), False),
66 98093aac Stavros Sachtouris
                (('small line', 'not so small line terms'), False),
67 98093aac Stavros Sachtouris
                ((['line', 'with', 'some', 'terms'], 'some terms'), True),
68 98093aac Stavros Sachtouris
                ((['line', 'with', 'some terms'], 'some terms'), False)):
69 98093aac Stavros Sachtouris
            self.assertEqual(self.HCLASS._match(*args), expected)
70 98093aac Stavros Sachtouris
71 98093aac Stavros Sachtouris
    def test_get(self):
72 98093aac Stavros Sachtouris
        history = self.HCLASS(self.file.name)
73 98093aac Stavros Sachtouris
        self.assertEqual(history.get(), [])
74 98093aac Stavros Sachtouris
75 98093aac Stavros Sachtouris
        sample_history = (
76 98093aac Stavros Sachtouris
            'kamaki history show\n',
77 98093aac Stavros Sachtouris
            'kamaki file list\n',
78 98093aac Stavros Sachtouris
            'kamaki touch pithos:f1\n',
79 98093aac Stavros Sachtouris
            'kamaki file info pithos:f1\n')
80 98093aac Stavros Sachtouris
        self.file.write(''.join(sample_history))
81 98093aac Stavros Sachtouris
        self.file.flush()
82 98093aac Stavros Sachtouris
83 98093aac Stavros Sachtouris
        expected = ['%s.  \t%s' % (
84 98093aac Stavros Sachtouris
            i + 1, event) for i, event in enumerate(sample_history)]
85 98093aac Stavros Sachtouris
        self.assertEqual(history.get(), expected)
86 98093aac Stavros Sachtouris
        self.assertEqual(history.get('kamaki'), expected)
87 98093aac Stavros Sachtouris
        self.assertEqual(history.get('file kamaki'), expected[1::2])
88 98093aac Stavros Sachtouris
        self.assertEqual(history.get('pithos:f1'), expected[2:])
89 98093aac Stavros Sachtouris
        self.assertEqual(history.get('touch pithos:f1'), expected[2:3])
90 98093aac Stavros Sachtouris
91 98093aac Stavros Sachtouris
        for limit in range(len(sample_history)):
92 98093aac Stavros Sachtouris
            self.assertEqual(history.get(limit=limit), expected[-limit:])
93 98093aac Stavros Sachtouris
            self.assertEqual(
94 98093aac Stavros Sachtouris
                history.get('kamaki', limit=limit), expected[-limit:])
95 98093aac Stavros Sachtouris
96 98093aac Stavros Sachtouris
    def test_add(self):
97 98093aac Stavros Sachtouris
        history = self.HCLASS(self.file.name)
98 98093aac Stavros Sachtouris
        some_strings = ('a brick', 'two bricks', 'another brick', 'A wall!')
99 98093aac Stavros Sachtouris
        for i, line in enumerate(some_strings):
100 98093aac Stavros Sachtouris
            history.add(line)
101 98093aac Stavros Sachtouris
            self.file.seek(0)
102 98093aac Stavros Sachtouris
            self.assertEqual(
103 98093aac Stavros Sachtouris
                self.file.read(), '\n'.join(some_strings[:(i + 1)]) + '\n')
104 98093aac Stavros Sachtouris
105 98093aac Stavros Sachtouris
    def test_clean(self):
106 98093aac Stavros Sachtouris
        content = 'a brick\ntwo bricks\nanother brick\nA wall!\n'
107 98093aac Stavros Sachtouris
        self.file.write(content)
108 98093aac Stavros Sachtouris
        self.file.flush()
109 98093aac Stavros Sachtouris
        self.file.seek(0)
110 98093aac Stavros Sachtouris
        self.assertEqual(self.file.read(), content)
111 98093aac Stavros Sachtouris
        history = self.HCLASS(self.file.name)
112 98093aac Stavros Sachtouris
        history.clean()
113 98093aac Stavros Sachtouris
        self.file.seek(0)
114 98093aac Stavros Sachtouris
        self.assertEqual(self.file.read(), '')
115 98093aac Stavros Sachtouris
116 98093aac Stavros Sachtouris
    def test_retrieve(self):
117 98093aac Stavros Sachtouris
        sample_history = (
118 98093aac Stavros Sachtouris
            'kamaki history show\n',
119 98093aac Stavros Sachtouris
            'kamaki file list\n',
120 98093aac Stavros Sachtouris
            'kamaki touch pithos:f1\n',
121 98093aac Stavros Sachtouris
            'kamaki file info pithos:f1\n',
122 98093aac Stavros Sachtouris
            'current / last command is always excluded')
123 98093aac Stavros Sachtouris
        self.file.write(''.join(sample_history))
124 98093aac Stavros Sachtouris
        self.file.flush()
125 98093aac Stavros Sachtouris
126 98093aac Stavros Sachtouris
        history = self.HCLASS(self.file.name)
127 98093aac Stavros Sachtouris
        self.assertRaises(ValueError, history.retrieve, 'must be number')
128 98093aac Stavros Sachtouris
        self.assertRaises(TypeError, history.retrieve, [1, 2, 3])
129 98093aac Stavros Sachtouris
130 98093aac Stavros Sachtouris
        for i in (0, len(sample_history), -len(sample_history)):
131 98093aac Stavros Sachtouris
            self.assertEqual(history.retrieve(i), None)
132 98093aac Stavros Sachtouris
        for i in range(1, len(sample_history)):
133 98093aac Stavros Sachtouris
            self.assertEqual(history.retrieve(i), sample_history[i - 1])
134 98093aac Stavros Sachtouris
            self.assertEqual(history.retrieve(- i), sample_history[- i - 1])
135 98093aac Stavros Sachtouris
136 98093aac Stavros Sachtouris
137 4769da6b Stavros Sachtouris
class LoggerMethods(TestCase):
138 4769da6b Stavros Sachtouris
139 4769da6b Stavros Sachtouris
    class PseudoLogger(object):
140 4769da6b Stavros Sachtouris
        level = 'some level'
141 4769da6b Stavros Sachtouris
        _setLevel_calls = []
142 4769da6b Stavros Sachtouris
        _addHandler_calls = []
143 4769da6b Stavros Sachtouris
144 4769da6b Stavros Sachtouris
        def setLevel(self, *args):
145 4769da6b Stavros Sachtouris
            self._setLevel_calls.append(args)
146 4769da6b Stavros Sachtouris
147 4769da6b Stavros Sachtouris
        def addHandler(self, *args):
148 4769da6b Stavros Sachtouris
            self._addHandler_calls.append(args)
149 4769da6b Stavros Sachtouris
150 4769da6b Stavros Sachtouris
    class PseudoHandler(object):
151 4769da6b Stavros Sachtouris
        _setFormatter_calls = []
152 4769da6b Stavros Sachtouris
153 4769da6b Stavros Sachtouris
        def setFormatter(self, *args):
154 4769da6b Stavros Sachtouris
            self._setFormatter_calls.append(args)
155 4769da6b Stavros Sachtouris
156 4769da6b Stavros Sachtouris
    def setUp(self):
157 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import LOG_FILE, _blacklist
158 4769da6b Stavros Sachtouris
        self.LF, self.BL = list(LOG_FILE), dict(_blacklist)
159 4769da6b Stavros Sachtouris
160 4769da6b Stavros Sachtouris
    def tearDown(self):
161 4769da6b Stavros Sachtouris
        self.PseudoLogger._setLevel_calls = []
162 4769da6b Stavros Sachtouris
        self.PseudoLogger._addHandler_calls = []
163 4769da6b Stavros Sachtouris
        self.PseudoLogger._setFormatter_calls = []
164 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import LOG_FILE, _blacklist
165 4769da6b Stavros Sachtouris
        for e in LOG_FILE:
166 4769da6b Stavros Sachtouris
            LOG_FILE.pop()
167 4769da6b Stavros Sachtouris
        for e in self.LF:
168 4769da6b Stavros Sachtouris
            LOG_FILE.append(e)
169 4769da6b Stavros Sachtouris
        _blacklist.clear()
170 4769da6b Stavros Sachtouris
        _blacklist.update(self.BL)
171 4769da6b Stavros Sachtouris
172 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.logging.getLogger', return_value=PseudoLogger())
173 4769da6b Stavros Sachtouris
    def test_deactivate(self, GL):
174 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import deactivate, _blacklist
175 4769da6b Stavros Sachtouris
        self.assertEqual(_blacklist, {})
176 4769da6b Stavros Sachtouris
        deactivate('some logger')
177 4769da6b Stavros Sachtouris
        GL.assert_called_once_with('some logger')
178 4769da6b Stavros Sachtouris
        self.assertEqual(
179 4769da6b Stavros Sachtouris
            _blacklist.get('some logger', None), self.PseudoLogger.level)
180 4769da6b Stavros Sachtouris
        from logging import CRITICAL
181 4769da6b Stavros Sachtouris
        self.assertEqual(self.PseudoLogger._setLevel_calls[-1], (CRITICAL, ))
182 4769da6b Stavros Sachtouris
183 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.logging.getLogger', return_value=PseudoLogger())
184 4769da6b Stavros Sachtouris
    def test_activate(self, GL):
185 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import activate
186 4769da6b Stavros Sachtouris
        activate('another logger')
187 4769da6b Stavros Sachtouris
        GL.assert_called_once_with('another logger')
188 4769da6b Stavros Sachtouris
        self.assertEqual(
189 4769da6b Stavros Sachtouris
            self.PseudoLogger._setLevel_calls[-1], (self.PseudoLogger.level, ))
190 4769da6b Stavros Sachtouris
191 4769da6b Stavros Sachtouris
    def test_get_log_filename(self):
192 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import get_log_filename, LOG_FILE
193 4769da6b Stavros Sachtouris
        f = NamedTemporaryFile()
194 4769da6b Stavros Sachtouris
        for e in LOG_FILE:
195 4769da6b Stavros Sachtouris
            LOG_FILE.pop()
196 4769da6b Stavros Sachtouris
        LOG_FILE.append(f.name)
197 4769da6b Stavros Sachtouris
        self.assertEqual(get_log_filename(), f.name)
198 4769da6b Stavros Sachtouris
        LOG_FILE.pop()
199 4769da6b Stavros Sachtouris
        LOG_FILE.append(2 * f.name)
200 4769da6b Stavros Sachtouris
        print('\n  Should print error msg here: ')
201 4769da6b Stavros Sachtouris
        self.assertEqual(get_log_filename(), None)
202 4769da6b Stavros Sachtouris
203 4769da6b Stavros Sachtouris
    def test_set_log_filename(self):
204 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import set_log_filename, LOG_FILE
205 4769da6b Stavros Sachtouris
        for n in ('some name', 'some other name'):
206 4769da6b Stavros Sachtouris
            set_log_filename(n)
207 4769da6b Stavros Sachtouris
            self.assertEqual(LOG_FILE[0], n)
208 4769da6b Stavros Sachtouris
209 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.get_logger', return_value=PseudoLogger())
210 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.logging.Formatter', return_value='f0rm4t')
211 4769da6b Stavros Sachtouris
    @patch(
212 4769da6b Stavros Sachtouris
        'kamaki.cli.logger.logging.StreamHandler',
213 4769da6b Stavros Sachtouris
        return_value=PseudoHandler())
214 4769da6b Stavros Sachtouris
    @patch(
215 4769da6b Stavros Sachtouris
        'kamaki.cli.logger.logging.FileHandler',
216 4769da6b Stavros Sachtouris
        return_value=PseudoHandler())
217 4769da6b Stavros Sachtouris
    def test__add_logger(self, FH, SH, F, GL):
218 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import _add_logger
219 4769da6b Stavros Sachtouris
        from logging import DEBUG
220 4769da6b Stavros Sachtouris
        stdf, cnt = '%(name)s\n %(message)s', 0
221 4769da6b Stavros Sachtouris
        for name, level, filename, fmt in product(
222 4769da6b Stavros Sachtouris
                ('my logger', ),
223 4769da6b Stavros Sachtouris
                ('my level', None),
224 4769da6b Stavros Sachtouris
                ('my filename', None),
225 4769da6b Stavros Sachtouris
                ('my fmt', None)):
226 4769da6b Stavros Sachtouris
            log = _add_logger(name, level, filename, fmt)
227 4769da6b Stavros Sachtouris
            self.assertTrue(isinstance(log, self.PseudoLogger))
228 4769da6b Stavros Sachtouris
            self.assertEqual(GL.mock_calls[-1], call(name))
229 4769da6b Stavros Sachtouris
            if filename:
230 4769da6b Stavros Sachtouris
                self.assertEqual(FH.mock_calls[-1], call(filename))
231 4769da6b Stavros Sachtouris
            else:
232 4769da6b Stavros Sachtouris
                self.assertEqual(SH.mock_calls[-1], call())
233 4769da6b Stavros Sachtouris
            self.assertEqual(F.mock_calls[-1], call(fmt or stdf))
234 4769da6b Stavros Sachtouris
            self.assertEqual(
235 4769da6b Stavros Sachtouris
                self.PseudoHandler._setFormatter_calls[-1], ('f0rm4t', ))
236 4769da6b Stavros Sachtouris
            cnt += 1
237 4769da6b Stavros Sachtouris
            self.assertEqual(len(self.PseudoLogger._addHandler_calls), cnt)
238 4769da6b Stavros Sachtouris
            h = self.PseudoLogger._addHandler_calls[-1]
239 4769da6b Stavros Sachtouris
            self.assertTrue(isinstance(h[0], self.PseudoHandler))
240 4769da6b Stavros Sachtouris
            l = self.PseudoLogger._setLevel_calls[-1]
241 4769da6b Stavros Sachtouris
            self.assertEqual(l, (level or DEBUG, ))
242 4769da6b Stavros Sachtouris
243 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.get_log_filename', return_value='my log fname')
244 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.get_logger', return_value='my get logger ret')
245 4769da6b Stavros Sachtouris
    def test_add_file_logger(self, GL, GLF):
246 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import add_file_logger
247 4769da6b Stavros Sachtouris
        with patch('kamaki.cli.logger._add_logger', return_value='AL') as AL:
248 4769da6b Stavros Sachtouris
            GLFcount = GLF.call_count
249 4769da6b Stavros Sachtouris
            for name, level, filename in product(
250 4769da6b Stavros Sachtouris
                    ('my name'), ('my level', None), ('my filename', None)):
251 4769da6b Stavros Sachtouris
                self.assertEqual(add_file_logger(name, level, filename), 'AL')
252 4769da6b Stavros Sachtouris
                self.assertEqual(AL.mock_calls[-1], call(
253 4769da6b Stavros Sachtouris
                    name, level, filename or 'my log fname',
254 4769da6b Stavros Sachtouris
                    fmt='%(name)s(%(levelname)s) %(asctime)s\n\t%(message)s'))
255 4769da6b Stavros Sachtouris
                if filename:
256 4769da6b Stavros Sachtouris
                    self.assertEqual(GLFcount, GLF.call_count)
257 4769da6b Stavros Sachtouris
                else:
258 4769da6b Stavros Sachtouris
                    GLFcount = GLF.call_count
259 4769da6b Stavros Sachtouris
                    self.assertEqual(GLF.mock_calls[-1], call())
260 4769da6b Stavros Sachtouris
        with patch('kamaki.cli.logger._add_logger', side_effect=Exception):
261 4769da6b Stavros Sachtouris
            self.assertEqual(add_file_logger('X'), 'my get logger ret')
262 4769da6b Stavros Sachtouris
            GL.assert_called_once_with('X')
263 4769da6b Stavros Sachtouris
264 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.get_logger', return_value='my get logger ret')
265 4769da6b Stavros Sachtouris
    def test_add_stream_logger(self, GL):
266 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import add_stream_logger
267 4769da6b Stavros Sachtouris
        with patch('kamaki.cli.logger._add_logger', return_value='AL') as AL:
268 4769da6b Stavros Sachtouris
            for name, level, fmt in product(
269 4769da6b Stavros Sachtouris
                    ('my name'), ('my level', None), ('my fmt', None)):
270 4769da6b Stavros Sachtouris
                self.assertEqual(add_stream_logger(name, level, fmt), 'AL')
271 4769da6b Stavros Sachtouris
                self.assertEqual(AL.mock_calls[-1], call(name, level, fmt=fmt))
272 4769da6b Stavros Sachtouris
        with patch('kamaki.cli.logger._add_logger', side_effect=Exception):
273 4769da6b Stavros Sachtouris
            self.assertEqual(add_stream_logger('X'), 'my get logger ret')
274 4769da6b Stavros Sachtouris
            GL.assert_called_once_with('X')
275 4769da6b Stavros Sachtouris
276 4769da6b Stavros Sachtouris
    @patch('kamaki.cli.logger.logging.getLogger', return_value=PseudoLogger())
277 4769da6b Stavros Sachtouris
    def test_get_logger(self, GL):
278 4769da6b Stavros Sachtouris
        from kamaki.cli.logger import get_logger
279 4769da6b Stavros Sachtouris
        get_logger('my logger name')
280 4769da6b Stavros Sachtouris
        GL.assert_called_once_with('my logger name')
281 4769da6b Stavros Sachtouris
282 4769da6b Stavros Sachtouris
283 2fde8651 Stavros Sachtouris
#  TestCase auxiliary methods
284 2fde8651 Stavros Sachtouris
285 2fde8651 Stavros Sachtouris
def runTestCase(cls, test_name, args=[], failure_collector=[]):
286 2fde8651 Stavros Sachtouris
    """
287 2fde8651 Stavros Sachtouris
    :param cls: (TestCase) a set of Tests
288 2fde8651 Stavros Sachtouris

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

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

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

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