Commit 2fde8651 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Setup unittest for CLI and apply to commant_tree

Refs: #4058

Only a __init__ and name methods are tested for now
parent 22c08927
......@@ -31,8 +31,6 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from kamaki.clients import Client
class Command(object):
"""Store a command and the next-level (2 levels)"""
......@@ -43,14 +41,15 @@ class Command(object):
help = ' '
def __init__(self, path, help=' ', subcommands={}, cmd_class=None):
assert path, 'Cannot initialize a command without a command path'
self.path = path
self.help = help
self.subcommands = dict(subcommands)
self.cmd_class = cmd_class
self.help = help or ''
self.subcommands = dict(subcommands) if subcommands else {}
self.cmd_class = cmd_class or None
@property
def name(self):
if self._name is None:
if not self._name:
self._name = self.path.split('_')[-1]
return str(self._name)
......
# Copyright 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
#from mock import patch, call
from unittest import TestCase
from itertools import product
from kamaki.cli import command_tree
class Command(TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test___init__(self):
for args in product(
(None, '', 'cmd'),
(None, '', 'Some help'),
(None, '', {}, dict(cmd0a=None, cmd0b=None)),
(None, command_tree.Command('cmd_cmd0'))):
path, help, subcommands, cmd_class = args
try:
cmd = command_tree.Command(*args)
except Exception as e:
if path:
raise
self.assertTrue(isinstance(e, AssertionError))
continue
self.assertEqual(cmd.help, help or '')
self.assertEqual(cmd.subcommands, subcommands or {})
self.assertEqual(cmd.cmd_class, cmd_class or None)
def test_name(self):
for path in ('cmd', 'cmd_cmd0', 'cmd_cmd0_cmd1', '', None):
if path:
cmd = command_tree.Command(path)
self.assertEqual(cmd.name, path.split('_')[-1])
else:
try:
command_tree.Command(path)
except Exception as e:
self.assertTrue(isinstance(e, AssertionError))
if __name__ == '__main__':
from sys import argv
from kamaki.cli.test import runTestCase
runTestCase(Command, 'Command', argv[1:])
# Copyright 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from mock import patch, call
from unittest import makeSuite, TestSuite, TextTestRunner, TestCase
from time import sleep
from inspect import getmembers, isclass
from itertools import product
from random import randint
from kamaki.cli.command_tree.test import Command
# TestCase auxiliary methods
def runTestCase(cls, test_name, args=[], failure_collector=[]):
"""
:param cls: (TestCase) a set of Tests
:param test_name: (str)
:param args: (list) these are prefixed with test_ and used as params when
instantiating cls
:param failure_collector: (list) collects info of test failures
:returns: (int) total # of run tests
"""
suite = TestSuite()
if args:
suite.addTest(cls('_'.join(['test'] + args)))
else:
suite.addTest(makeSuite(cls))
print('* Test * %s *' % test_name)
r = TextTestRunner(verbosity=2).run(suite)
failure_collector += r.failures
return r.testsRun
def get_test_classes(module=__import__(__name__), name=''):
module_stack = [module]
while module_stack:
module = module_stack[-1]
module_stack = module_stack[:-1]
for objname, obj in getmembers(module):
if (objname == name or not name):
if isclass(obj) and objname != 'TestCase' and (
issubclass(obj, TestCase)):
yield (obj, objname)
def main(argv):
found = False
failure_collector = list()
num_of_tests = 0
for cls, name in get_test_classes(name=argv[1] if len(argv) > 1 else ''):
found = True
num_of_tests += runTestCase(cls, name, argv[2:], failure_collector)
if not found:
print('Test "%s" not found' % ' '.join(argv[1:]))
else:
for i, failure in enumerate(failure_collector):
print('Failure %s: ' % (i + 1))
for field in failure:
print('\t%s' % field)
print('\nTotal tests run: %s' % num_of_tests)
print('Total failures: %s' % len(failure_collector))
if __name__ == '__main__':
from sys import argv
main(argv)
......@@ -62,6 +62,7 @@ setup(
packages=[
'kamaki',
'kamaki.cli',
'kamaki.cli.command_tree',
'kamaki.cli.commands',
'kamaki.clients',
'kamaki.clients.utils',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment