Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / test.py @ 98093aac

History | View | Annotate | Download (7.2 kB)

1
# Copyright 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from unittest import makeSuite, TestSuite, TextTestRunner, TestCase
35
from inspect import getmembers, isclass
36
from tempfile import NamedTemporaryFile
37

    
38
from kamaki.cli.command_tree.test import Command, CommandTree
39
from kamaki.cli.argument.test import (
40
    Argument, ConfigArgument, RuntimeConfigArgument, FlagArgument,
41
    ValueArgument, IntArgument, DateArgument, VersionArgument,
42
    KeyValueArgument, ProgressBarArgument, ArgumentParseManager)
43

    
44

    
45
class History(TestCase):
46

    
47
    def setUp(self):
48
        from kamaki.cli.history import History as HClass
49
        self.HCLASS = HClass
50
        self.file = NamedTemporaryFile()
51

    
52
    def tearDown(self):
53
        self.file.close()
54

    
55
    def test__match(self):
56
        self.assertRaises(AttributeError, self.HCLASS._match, 'ok', 42)
57
        self.assertRaises(TypeError, self.HCLASS._match, 2.71, 'ok')
58
        for args, expected in (
59
                (('XXX', None), True),
60
                ((None, None), True),
61
                (('this line has some terms', 'some terms'), True),
62
                (('this line has some terms', 'some bad terms'), False),
63
                (('small line', 'not so small line terms'), False),
64
                ((['line', 'with', 'some', 'terms'], 'some terms'), True),
65
                ((['line', 'with', 'some terms'], 'some terms'), False)):
66
            self.assertEqual(self.HCLASS._match(*args), expected)
67

    
68
    def test_get(self):
69
        history = self.HCLASS(self.file.name)
70
        self.assertEqual(history.get(), [])
71

    
72
        sample_history = (
73
            'kamaki history show\n',
74
            'kamaki file list\n',
75
            'kamaki touch pithos:f1\n',
76
            'kamaki file info pithos:f1\n')
77
        self.file.write(''.join(sample_history))
78
        self.file.flush()
79

    
80
        expected = ['%s.  \t%s' % (
81
            i + 1, event) for i, event in enumerate(sample_history)]
82
        self.assertEqual(history.get(), expected)
83
        self.assertEqual(history.get('kamaki'), expected)
84
        self.assertEqual(history.get('file kamaki'), expected[1::2])
85
        self.assertEqual(history.get('pithos:f1'), expected[2:])
86
        self.assertEqual(history.get('touch pithos:f1'), expected[2:3])
87

    
88
        for limit in range(len(sample_history)):
89
            self.assertEqual(history.get(limit=limit), expected[-limit:])
90
            self.assertEqual(
91
                history.get('kamaki', limit=limit), expected[-limit:])
92

    
93
    def test_add(self):
94
        history = self.HCLASS(self.file.name)
95
        some_strings = ('a brick', 'two bricks', 'another brick', 'A wall!')
96
        for i, line in enumerate(some_strings):
97
            history.add(line)
98
            self.file.seek(0)
99
            self.assertEqual(
100
                self.file.read(), '\n'.join(some_strings[:(i + 1)]) + '\n')
101

    
102
    def test_clean(self):
103
        content = 'a brick\ntwo bricks\nanother brick\nA wall!\n'
104
        self.file.write(content)
105
        self.file.flush()
106
        self.file.seek(0)
107
        self.assertEqual(self.file.read(), content)
108
        history = self.HCLASS(self.file.name)
109
        history.clean()
110
        self.file.seek(0)
111
        self.assertEqual(self.file.read(), '')
112

    
113
    def test_retrieve(self):
114
        sample_history = (
115
            'kamaki history show\n',
116
            'kamaki file list\n',
117
            'kamaki touch pithos:f1\n',
118
            'kamaki file info pithos:f1\n',
119
            'current / last command is always excluded')
120
        self.file.write(''.join(sample_history))
121
        self.file.flush()
122

    
123
        history = self.HCLASS(self.file.name)
124
        self.assertRaises(ValueError, history.retrieve, 'must be number')
125
        self.assertRaises(TypeError, history.retrieve, [1, 2, 3])
126

    
127
        for i in (0, len(sample_history), -len(sample_history)):
128
            self.assertEqual(history.retrieve(i), None)
129
        for i in range(1, len(sample_history)):
130
            self.assertEqual(history.retrieve(i), sample_history[i - 1])
131
            self.assertEqual(history.retrieve(- i), sample_history[- i - 1])
132

    
133

    
134
#  TestCase auxiliary methods
135

    
136
def runTestCase(cls, test_name, args=[], failure_collector=[]):
137
    """
138
    :param cls: (TestCase) a set of Tests
139

140
    :param test_name: (str)
141

142
    :param args: (list) these are prefixed with test_ and used as params when
143
        instantiating cls
144

145
    :param failure_collector: (list) collects info of test failures
146

147
    :returns: (int) total # of run tests
148
    """
149
    suite = TestSuite()
150
    if args:
151
        suite.addTest(cls('_'.join(['test'] + args)))
152
    else:
153
        suite.addTest(makeSuite(cls))
154
    print('* Test * %s *' % test_name)
155
    r = TextTestRunner(verbosity=2).run(suite)
156
    failure_collector += r.failures
157
    return r.testsRun
158

    
159

    
160
def get_test_classes(module=__import__(__name__), name=''):
161
    module_stack = [module]
162
    while module_stack:
163
        module = module_stack[-1]
164
        module_stack = module_stack[:-1]
165
        for objname, obj in getmembers(module):
166
            if (objname == name or not name):
167
                if isclass(obj) and objname != 'TestCase' and (
168
                        issubclass(obj, TestCase)):
169
                    yield (obj, objname)
170

    
171

    
172
def main(argv):
173
    found = False
174
    failure_collector = list()
175
    num_of_tests = 0
176
    for cls, name in get_test_classes(name=argv[1] if len(argv) > 1 else ''):
177
        found = True
178
        num_of_tests += runTestCase(cls, name, argv[2:], failure_collector)
179
    if not found:
180
        print('Test "%s" not found' % ' '.join(argv[1:]))
181
    else:
182
        for i, failure in enumerate(failure_collector):
183
            print('Failure %s: ' % (i + 1))
184
            for field in failure:
185
                print('\t%s' % field)
186
        print('\nTotal tests run: %s' % num_of_tests)
187
        print('Total failures: %s' % len(failure_collector))
188

    
189

    
190
if __name__ == '__main__':
191
    from sys import argv
192
    main(argv)