Merge "Tests added for utils."
authorMorgan Richomme <morgan.richomme@orange.com>
Thu, 12 Jan 2017 08:58:13 +0000 (08:58 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Thu, 12 Jan 2017 08:58:13 +0000 (08:58 +0000)
17 files changed:
.coveragerc [new file with mode: 0644]
INFO
functest/ci/check_os.sh
functest/opnfv_tests/openstack/healthcheck/healthcheck.sh
functest/opnfv_tests/sdn/odl/odl.py
functest/tests/unit/cli/__init__.py [new file with mode: 0644]
functest/tests/unit/cli/commands/__init__.py [new file with mode: 0644]
functest/tests/unit/cli/commands/test_cli_env.py [new file with mode: 0644]
functest/tests/unit/cli/commands/test_cli_os.py [new file with mode: 0644]
functest/tests/unit/cli/commands/test_cli_testcase.py [new file with mode: 0644]
functest/tests/unit/cli/commands/test_cli_tier.py [new file with mode: 0644]
functest/tests/unit/cli/test_cli_base.py [new file with mode: 0644]
functest/tests/unit/core/test_testcase_base.py
functest/tests/unit/odl/test_odl.py
functest/tests/unit/utils/test_functest_utils.py
run_unit_tests.sh
test-requirements.txt

diff --git a/.coveragerc b/.coveragerc
new file mode 100644 (file)
index 0000000..fe258c6
--- /dev/null
@@ -0,0 +1,3 @@
+[report]
+exclude_lines =
+    if __name__ == .__main__.:
diff --git a/INFO b/INFO
index 07145bd..6f8963e 100644 (file)
--- a/INFO
+++ b/INFO
@@ -12,7 +12,7 @@ Repository: functest
 
 Committers:
 yaohelan@huawei.com
-serena.feng.711@gmail.com
+feng.xiaowei@zte.com.cn
 ollivier.cedric@gmail.com
 jose.lausuch@ericsson.com
 morgan.richomme@orange.com
index 053796d..e247102 100755 (executable)
@@ -24,7 +24,7 @@ fi
 
 
 echo "Checking OpenStack endpoints:"
-publicURL=$OS_AUTH_URL
+publicURL=$(openstack catalog show  identity |awk '/public/ {print $4}')
 publicIP=$(echo $publicURL|sed 's/^.*http\:\/\///'|sed 's/.[^:]*$//')
 publicPort=$(echo $publicURL|sed 's/^.*://'|sed 's/\/.*$//')
 echo ">>Verifying connectivity to the public endpoint $publicIP:$publicPort..."
index e27cf4b..57aa0c7 100755 (executable)
@@ -228,10 +228,11 @@ sleep ${wait_time}
 
 
 # Check if flavor exists
-if [[ -z $(nova flavor-list|grep $flavor) ]]; then
+if [[ -z $(openstack flavor list -f value -c Name | fgrep -x $flavor) ]]; then
     # if given flavor doesn't exist, we create one
     debug "Flavor $flavor doesn't exist. Creating a new flavor."
-    nova flavor-create --is-public false ${flavor} auto 512 1 1 --is-public True
+    openstack flavor create ${flavor} --id auto --ram 512 --disk 1 --vcpus 1
+    openstack flavor set ${flavor} --property hw:mem_page_size=any
 fi
 debug "Using flavor $flavor to boot the instances."
 
index 0905e55..45b313d 100755 (executable)
@@ -15,7 +15,7 @@ import re
 import sys
 import urlparse
 
-from robot.api import ExecutionResult, ResultVisitor
+import robot.api
 from robot.errors import RobotError
 import robot.run
 from robot.utils.robottime import timestamp_to_secs
@@ -25,7 +25,7 @@ import functest.utils.functest_logger as ft_logger
 import functest.utils.openstack_utils as op_utils
 
 
-class ODLResultVisitor(ResultVisitor):
+class ODLResultVisitor(robot.api.ResultVisitor):
 
     def __init__(self):
         self._data = []
@@ -79,7 +79,7 @@ class ODLTests(testcase_base.TestcaseBase):
 
     def parse_results(self):
         xml_file = os.path.join(self.res_dir, 'output.xml')
-        result = ExecutionResult(xml_file)
+        result = robot.api.ExecutionResult(xml_file)
         visitor = ODLResultVisitor()
         result.visit(visitor)
         self.criteria = result.suite.status
@@ -180,44 +180,52 @@ class ODLTests(testcase_base.TestcaseBase):
         return self.main(**kwargs)
 
 
+class ODLParser():
+
+    def __init__(self):
+        self.parser = argparse.ArgumentParser()
+        self.parser.add_argument(
+            '-k', '--keystoneip', help='Keystone IP',
+            default='127.0.0.1')
+        self.parser.add_argument(
+            '-n', '--neutronip', help='Neutron IP',
+            default='127.0.0.1')
+        self.parser.add_argument(
+            '-a', '--osusername', help='Username for OpenStack',
+            default='admin')
+        self.parser.add_argument(
+            '-b', '--ostenantname', help='Tenantname for OpenStack',
+            default='admin')
+        self.parser.add_argument(
+            '-c', '--ospassword', help='Password for OpenStack',
+            default='admin')
+        self.parser.add_argument(
+            '-o', '--odlip', help='OpenDaylight IP',
+            default='127.0.0.1')
+        self.parser.add_argument(
+            '-w', '--odlwebport', help='OpenDaylight Web Portal Port',
+            default='8080')
+        self.parser.add_argument(
+            '-r', '--odlrestconfport', help='OpenDaylight RESTConf Port',
+            default='8181')
+        self.parser.add_argument(
+            '-d', '--odlusername', help='Username for ODL',
+            default='admin')
+        self.parser.add_argument(
+            '-e', '--odlpassword', help='Password for ODL',
+            default='admin')
+        self.parser.add_argument(
+            '-p', '--pushtodb', help='Push results to DB',
+            action='store_true')
+
+    def parse_args(self, argv=[]):
+        return vars(self.parser.parse_args(argv))
+
+
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser()
-    parser.add_argument('-k', '--keystoneip',
-                        help='Keystone IP',
-                        default='127.0.0.1')
-    parser.add_argument('-n', '--neutronip',
-                        help='Neutron IP',
-                        default='127.0.0.1')
-    parser.add_argument('-a', '--osusername',
-                        help='Username for OpenStack',
-                        default='admin')
-    parser.add_argument('-b', '--ostenantname',
-                        help='Tenantname for OpenStack',
-                        default='admin')
-    parser.add_argument('-c', '--ospassword',
-                        help='Password for OpenStack',
-                        default='admin')
-    parser.add_argument('-o', '--odlip',
-                        help='OpenDaylight IP',
-                        default='127.0.0.1')
-    parser.add_argument('-w', '--odlwebport',
-                        help='OpenDaylight Web Portal Port',
-                        default='8080')
-    parser.add_argument('-r', '--odlrestconfport',
-                        help='OpenDaylight RESTConf Port',
-                        default='8181')
-    parser.add_argument('-d', '--odlusername',
-                        help='Username for ODL',
-                        default='admin')
-    parser.add_argument('-e', '--odlpassword',
-                        help='Password for ODL',
-                        default='admin')
-    parser.add_argument('-p', '--pushtodb',
-                        help='Push results to DB',
-                        action='store_true')
-
-    args = vars(parser.parse_args())
     odl = ODLTests()
+    parser = ODLParser()
+    args = parser.parse_args(sys.argv[1:])
     try:
         result = odl.main(**args)
         if result != testcase_base.TestcaseBase.EX_OK:
diff --git a/functest/tests/unit/cli/__init__.py b/functest/tests/unit/cli/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/functest/tests/unit/cli/commands/__init__.py b/functest/tests/unit/cli/commands/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/functest/tests/unit/cli/commands/test_cli_env.py b/functest/tests/unit/cli/commands/test_cli_env.py
new file mode 100644 (file)
index 0000000..f70761d
--- /dev/null
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+from git.exc import NoSuchPathError
+import mock
+
+mock.patch('logging.FileHandler').start()  # noqa
+from functest.cli.commands import cli_env
+from functest.utils.constants import CONST
+from functest.tests.unit import test_utils
+
+
+class CliEnvTesting(unittest.TestCase):
+
+    logging.disable(logging.CRITICAL)
+
+    def setUp(self):
+        self.cli_environ = cli_env.CliEnv()
+
+    @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+    def test_prepare_default(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/prepare_env.py start" %
+               CONST.dir_repo_functest)
+        self.cli_environ.prepare()
+        mock_ft_utils.assert_called_with(cmd)
+
+    @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+    def test_prepare_missing_status(self, mock_ft_utils, mock_os):
+        with mock.patch('__builtin__.raw_input', return_value="y"), \
+                mock.patch('functest.cli.commands.cli_testcase.os.remove') \
+                as mock_os_remove:
+            cmd = ("python %s/functest/ci/prepare_env.py start" %
+                   CONST.dir_repo_functest)
+            self.cli_environ.prepare()
+            mock_os_remove.assert_called_once_with(CONST.env_active)
+            mock_ft_utils.assert_called_with(cmd)
+
+    def _test_show_missing_env_var(self, var, *args):
+        if var == 'INSTALLER_TYPE':
+            CONST.INSTALLER_TYPE = None
+            reg_string = "|  INSTALLER: Unknown, \S+\s*|"
+        elif var == 'INSTALLER_IP':
+            CONST.INSTALLER_IP = None
+            reg_string = "|  INSTALLER: \S+, Unknown\s*|"
+        elif var == 'SCENARIO':
+            CONST.DEPLOY_SCENARIO = None
+            reg_string = "|   SCENARIO: Unknown\s*|"
+        elif var == 'NODE':
+            CONST.NODE_NAME = None
+            reg_string = "|        POD: Unknown\s*|"
+        elif var == 'BUILD_TAG':
+            CONST.BUILD_TAG = None
+            reg_string = "|  BUILD TAG: None|"
+        elif var == 'DEBUG':
+            CONST.CI_DEBUG = None
+            reg_string = "| DEBUG FLAG: false\s*|"
+        elif var == 'STATUS':
+            reg_string = "|     STATUS: not ready\s*|"
+
+        with mock.patch('functest.cli.commands.cli_env.click.echo') \
+                as mock_click_echo:
+            self.cli_environ.show()
+            mock_click_echo.assert_called_with(test_utils.
+                                               RegexMatch(reg_string))
+
+    @mock.patch('functest.cli.commands.cli_env.git.Repo')
+    def test_show_missing_ci_installer_type(self, *args):
+        self._test_show_missing_env_var('INSTALLER_TYPE', *args)
+
+    @mock.patch('functest.cli.commands.cli_env.git.Repo')
+    def test_show_missing_ci_installer_ip(self, *args):
+        self._test_show_missing_env_var('INSTALLER_IP', *args)
+
+    @mock.patch('functest.cli.commands.cli_env.git.Repo')
+    def test_show_missing_ci_scenario(self, *args):
+        self._test_show_missing_env_var('SCENARIO', *args)
+
+    @mock.patch('functest.cli.commands.cli_env.git.Repo')
+    def test_show_missing_ci_node(self, *args):
+        self._test_show_missing_env_var('NODE', *args)
+
+    @mock.patch('functest.cli.commands.cli_env.git.Repo')
+    def test_show_missing_ci_build_tag(self, *args):
+        self._test_show_missing_env_var('BUILD_TAG', *args)
+
+    @mock.patch('functest.cli.commands.cli_env.git.Repo')
+    def test_show_missing_ci_debug(self, *args):
+        self._test_show_missing_env_var('DEBUG', *args)
+
+    @mock.patch('functest.cli.commands.cli_env.git.Repo')
+    @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+                return_value=False)
+    def test_show_missing_environment(self, *args):
+        self._test_show_missing_env_var('STATUS', *args)
+
+    @mock.patch('functest.cli.commands.cli_env.os.path.exists',
+                return_value=False)
+    def test_show_missing_git_repo_dir(self, *args):
+        CONST.dir_repo_functest = None
+        self.assertRaises(NoSuchPathError, lambda: self.cli_environ.show())
+
+    @mock.patch('functest.cli.commands.cli_env.click.echo')
+    @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+                return_value=True)
+    def test_status_environment_present(self, mock_path, mock_click_echo):
+        self.assertEqual(self.cli_environ.status(), 0)
+        mock_click_echo.assert_called_with("Functest environment"
+                                           " ready to run tests.\n")
+
+    @mock.patch('functest.cli.commands.cli_env.click.echo')
+    @mock.patch('functest.cli.commands.cli_env.os.path.isfile',
+                return_value=False)
+    def test_status_environment_absent(self, mock_path, mock_click_echo):
+        self.assertEqual(self.cli_environ.status(), 1)
+        mock_click_echo.assert_called_with("Functest environment"
+                                           " is not installed.\n")
+
+
+if __name__ == "__main__":
+    unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_os.py b/functest/tests/unit/cli/commands/test_cli_os.py
new file mode 100644 (file)
index 0000000..f0e58c6
--- /dev/null
@@ -0,0 +1,238 @@
+#!/usr/bin/env python
+#
+# jose.lausuch@ericsson.com
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+
+import logging
+import unittest
+import os
+
+import mock
+
+from functest.cli.commands import cli_os
+from functest.utils.constants import CONST
+
+
+class CliOpenStackTesting(unittest.TestCase):
+    logging.disable(logging.CRITICAL)
+
+    def setUp(self):
+        self.endpoint_ip = 'test_ip'
+        self.os_auth_url = 'http://test_ip:test_port/v2.0'
+        self.installer_type = 'test_installer_type'
+        self.installer_ip = 'test_installer_ip'
+        self.openstack_creds = 'test_openstack_creds'
+        self.dir_repo_functest = 'test_dir_repo_functest'
+        self.snapshot_file = 'test_snapshot_file'
+        self.cli_os = cli_os.CliOpenStack()
+
+    def test_ping_endpoint_default(self):
+        self.cli_os.os_auth_url = self.os_auth_url
+        self.cli_os.endpoint_ip = self.endpoint_ip
+        with mock.patch('functest.cli.commands.cli_os.os.system',
+                        return_value=0):
+            self.assertEqual(self.cli_os.ping_endpoint(), 0)
+
+    @mock.patch('functest.cli.commands.cli_os.exit', side_effect=Exception)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_ping_endpoint_missing_auth_url(self, mock_click_echo,
+                                            mock_exit):
+        with self.assertRaises(Exception):
+            self.cli_os.os_auth_url = None
+            self.cli_os.ping_endpoint()
+            mock_click_echo.assert_called_once_with("Source the OpenStack "
+                                                    "credentials first '. "
+                                                    "$creds'")
+
+    @mock.patch('functest.cli.commands.cli_os.exit')
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_ping_endpoint_os_system_fails(self, mock_click_echo,
+                                           mock_exit):
+        self.cli_os.os_auth_url = self.os_auth_url
+        self.cli_os.endpoint_ip = self.endpoint_ip
+        with mock.patch('functest.cli.commands.cli_os.os.system',
+                        return_value=1):
+            self.cli_os.ping_endpoint()
+            mock_click_echo.assert_called_once_with("Cannot talk to the "
+                                                    "endpoint %s\n" %
+                                                    self.endpoint_ip)
+            mock_exit.assert_called_once_with(0)
+
+    @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_fetch_credentials_default(self, mock_click_echo,
+                                       mock_os_path,
+                                       mock_ftutils_execute):
+        CONST.INSTALLER_TYPE = self.installer_type
+        CONST.INSTALLER_IP = self.installer_ip
+        cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+               % (CONST.dir_repos,
+                  self.openstack_creds,
+                  self.installer_type,
+                  self.installer_ip))
+        self.cli_os.openstack_creds = self.openstack_creds
+        self.cli_os.fetch_credentials()
+        mock_click_echo.assert_called_once_with("Fetching credentials from "
+                                                "installer node '%s' with "
+                                                "IP=%s.." %
+                                                (self.installer_type,
+                                                 self.installer_ip))
+        mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+    @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_fetch_credentials_missing_installer_type(self, mock_click_echo,
+                                                      mock_os_path,
+                                                      mock_ftutils_execute):
+        installer_type = None
+        installer_ip = self.installer_ip
+        CONST.INSTALLER_TYPE = installer_type
+        CONST.INSTALLER_IP = installer_ip
+        cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+               % (CONST.dir_repos,
+                  self.openstack_creds,
+                  installer_type,
+                  installer_ip))
+        self.cli_os.openstack_creds = self.openstack_creds
+        self.cli_os.fetch_credentials()
+        mock_click_echo.assert_any_call("The environment variable "
+                                        "'INSTALLER_TYPE' is not"
+                                        "defined. Please export it")
+        mock_click_echo.assert_any_call("Fetching credentials from "
+                                        "installer node '%s' with "
+                                        "IP=%s.." %
+                                        (installer_type,
+                                         installer_ip))
+        mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+    @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_fetch_credentials_missing_installer_ip(self, mock_click_echo,
+                                                    mock_os_path,
+                                                    mock_ftutils_execute):
+        installer_type = self.installer_type
+        installer_ip = None
+        CONST.INSTALLER_TYPE = installer_type
+        CONST.INSTALLER_IP = installer_ip
+        cmd = ("%s/releng/utils/fetch_os_creds.sh -d %s -i %s -a %s"
+               % (CONST.dir_repos,
+                  self.openstack_creds,
+                  installer_type,
+                  installer_ip))
+        self.cli_os.openstack_creds = self.openstack_creds
+        self.cli_os.fetch_credentials()
+        mock_click_echo.assert_any_call("The environment variable "
+                                        "'INSTALLER_IP' is not"
+                                        "defined. Please export it")
+        mock_click_echo.assert_any_call("Fetching credentials from "
+                                        "installer node '%s' with "
+                                        "IP=%s.." %
+                                        (installer_type,
+                                         installer_ip))
+        mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+    @mock.patch('functest.cli.commands.cli_os.ft_utils.execute_command')
+    def test_check(self, mock_ftutils_execute):
+        with mock.patch.object(self.cli_os, 'ping_endpoint'):
+            CONST.dir_repo_functest = self.dir_repo_functest
+            cmd = CONST.dir_repo_functest + "/functest/ci/check_os.sh"
+            self.cli_os.check()
+            mock_ftutils_execute.assert_called_once_with(cmd, verbose=False)
+
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_snapshot_create(self, mock_click_echo, mock_os_path):
+        with mock.patch.object(self.cli_os, 'ping_endpoint'), \
+                mock.patch('functest.cli.commands.cli_os.os_snapshot.main') \
+                as mock_os_snapshot:
+            self.cli_os.snapshot_create()
+            mock_click_echo.assert_called_once_with("Generating Openstack "
+                                                    "snapshot...")
+            self.assertTrue(mock_os_snapshot.called)
+
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_snapshot_create_overwrite(self, mock_click_echo, mock_os_path):
+        with mock.patch('__builtin__.raw_input', return_value="y") \
+                as mock_raw_input, \
+                mock.patch.object(self.cli_os, 'ping_endpoint'), \
+                mock.patch('functest.cli.commands.cli_os.os_snapshot.main') \
+                as mock_os_snapshot:
+            self.cli_os.snapshot_create()
+            mock_click_echo.assert_called_once_with("Generating Openstack "
+                                                    "snapshot...")
+            mock_raw_input.assert_any_call("It seems there is already an "
+                                           "OpenStack snapshot. Do you want "
+                                           "to overwrite it with the current "
+                                           "OpenStack status? [y|n]\n")
+            self.assertTrue(mock_os_snapshot.called)
+
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_snapshot_show_missing_snap(self, mock_click_echo, mock_os_path):
+        self.cli_os.snapshot_show()
+        mock_click_echo.assert_called_once_with("There is no OpenStack "
+                                                "snapshot created. To create "
+                                                "one run the command "
+                                                "'functest openstack "
+                                                "snapshot-create'")
+
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_snapshot_show_default(self, mock_click_echo, mock_os_path):
+        with mock.patch('__builtin__.open', mock.mock_open(read_data='0')) \
+                as m:
+            self.cli_os.snapshot_file = self.snapshot_file
+            self.cli_os.snapshot_show()
+            m.assert_called_once_with(self.snapshot_file, 'r')
+            mock_click_echo.assert_called_once_with("\n0")
+
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_clean(self, mock_click_echo, mock_os_path):
+        with mock.patch.object(self.cli_os, 'ping_endpoint'), \
+                mock.patch('functest.cli.commands.cli_os.os_clean.main') \
+                as mock_os_clean:
+            self.cli_os.clean()
+            self.assertTrue(mock_os_clean.called)
+
+    @mock.patch('functest.cli.commands.cli_os.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_clean_missing_file(self, mock_click_echo, mock_os_path):
+        with mock.patch.object(self.cli_os, 'ping_endpoint'):
+            self.cli_os.clean()
+            mock_click_echo.assert_called_once_with("Not possible to clean "
+                                                    "OpenStack without a "
+                                                    "snapshot. This could "
+                                                    "cause problems. "
+                                                    "Run first the command "
+                                                    "'functest openstack "
+                                                    "snapshot-create'")
+
+    @mock.patch('functest.cli.commands.cli_os.click.echo')
+    def test_show_credentials(self, mock_click_echo):
+        key = 'OS_KEY'
+        value = 'OS_VALUE'
+        with mock.patch.dict(os.environ, {key: value}):
+            self.cli_os.show_credentials()
+            mock_click_echo.assert_any_call("{}={}".format(key, value))
+
+
+if __name__ == "__main__":
+    unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_testcase.py b/functest/tests/unit/cli/commands/test_cli_testcase.py
new file mode 100644 (file)
index 0000000..39c8139
--- /dev/null
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+
+import logging
+import unittest
+
+import mock
+
+from functest.cli.commands import cli_testcase
+from functest.utils.constants import CONST
+
+
+class CliTestCasesTesting(unittest.TestCase):
+
+    logging.disable(logging.CRITICAL)
+
+    def setUp(self):
+        self.testname = 'testname'
+        with mock.patch('functest.cli.commands.cli_testcase.tb'):
+            self.cli_tests = cli_testcase.CliTestcase()
+
+    @mock.patch('functest.cli.commands.cli_testcase.vacation.main')
+    def test_run_vacation(self, mock_method):
+        self.cli_tests.run('vacation')
+        self.assertTrue(mock_method.called)
+
+    @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+    def test_run_missing_env_file(self, mock_click_echo, mock_os):
+        self.cli_tests.run(self.testname)
+        mock_click_echo.assert_called_with("Functest environment is not ready."
+                                           " Run first 'functest env prepare'")
+
+    @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+    def test_run_default(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/run_tests.py "
+               "%s -t %s" % (CONST.dir_repo_functest, "-n -r ", self.testname))
+        self.cli_tests.run(self.testname, noclean=True, report=True)
+        mock_ft_utils.assert_called_with(cmd)
+
+    @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+    def test_run_noclean_missing_report(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/run_tests.py "
+               "%s -t %s" % (CONST.dir_repo_functest, "-n ", self.testname))
+        self.cli_tests.run(self.testname, noclean=True, report=False)
+        mock_ft_utils.assert_called_with(cmd)
+
+    @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+    def test_run_report_missing_noclean(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/run_tests.py "
+               "%s -t %s" % (CONST.dir_repo_functest, "-r ", self.testname))
+        self.cli_tests.run(self.testname, noclean=False, report=True)
+        mock_ft_utils.assert_called_with(cmd)
+
+    @mock.patch('functest.cli.commands.cli_testcase.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_testcase.ft_utils.execute_command')
+    def test_run_missing_noclean_report(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/run_tests.py "
+               "%s -t %s" % (CONST.dir_repo_functest, "", self.testname))
+        self.cli_tests.run(self.testname, noclean=False, report=False)
+        mock_ft_utils.assert_called_with(cmd)
+
+    @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+    def test_list(self, mock_click_echo):
+        with mock.patch.object(self.cli_tests.tiers, 'get_tiers',
+                               return_value=[]):
+            self.cli_tests.list()
+            mock_click_echo.assert_called_with("")
+
+    @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+    def test_show_default_desc_none(self, mock_click_echo):
+        with mock.patch.object(self.cli_tests.tiers, 'get_test',
+                               return_value=None):
+            self.cli_tests.show(self.testname)
+            mock_click_echo.assert_any_call("The test case '%s' "
+                                            "does not exist or is"
+                                            " not supported."
+                                            % self.testname)
+
+    @mock.patch('functest.cli.commands.cli_testcase.click.echo')
+    def test_show_default(self, mock_click_echo):
+        mock_obj = mock.Mock()
+        with mock.patch.object(self.cli_tests.tiers, 'get_test',
+                               return_value=mock_obj):
+            self.cli_tests.show(self.testname)
+            mock_click_echo.assert_called_with(mock_obj)
+
+
+if __name__ == "__main__":
+    unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/commands/test_cli_tier.py b/functest/tests/unit/cli/commands/test_cli_tier.py
new file mode 100644 (file)
index 0000000..802359f
--- /dev/null
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+
+import logging
+import unittest
+
+import mock
+
+from functest.cli.commands import cli_tier
+from functest.utils.constants import CONST
+
+
+class CliTierTesting(unittest.TestCase):
+
+    logging.disable(logging.CRITICAL)
+
+    def setUp(self):
+        self.tiername = 'tiername'
+        self.testnames = 'testnames'
+        with mock.patch('functest.cli.commands.cli_tier.tb'):
+            self.cli_tier = cli_tier.CliTier()
+
+    @mock.patch('functest.cli.commands.cli_tier.click.echo')
+    def test_list(self, mock_click_echo):
+        with mock.patch.object(self.cli_tier.tiers, 'get_tiers',
+                               return_value=[]):
+            self.cli_tier.list()
+            mock_click_echo.assert_called_with("")
+
+    @mock.patch('functest.cli.commands.cli_tier.click.echo')
+    def test_show_default(self, mock_click_echo):
+        with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+                               return_value=self.tiername):
+            self.cli_tier.show(self.tiername)
+            mock_click_echo.assert_called_with(self.tiername)
+
+    @mock.patch('functest.cli.commands.cli_tier.click.echo')
+    def test_show_missing_tier(self, mock_click_echo):
+        with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+                               return_value=None), \
+            mock.patch.object(self.cli_tier.tiers, 'get_tier_names',
+                              return_value='tiernames'):
+            self.cli_tier.show(self.tiername)
+            mock_click_echo.assert_called_with("The tier with name '%s' does "
+                                               "not exist. Available tiers are"
+                                               ":\n  %s\n" % (self.tiername,
+                                                              'tiernames'))
+
+    @mock.patch('functest.cli.commands.cli_tier.click.echo')
+    def test_gettests_default(self, mock_click_echo):
+        mock_obj = mock.Mock()
+        attrs = {'get_test_names.return_value': self.testnames}
+        mock_obj.configure_mock(**attrs)
+
+        with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+                               return_value=mock_obj):
+            self.cli_tier.gettests(self.tiername)
+            mock_click_echo.assert_called_with("Test cases in tier "
+                                               "'%s':\n %s\n" % (self.tiername,
+                                                                 self.testnames
+                                                                 ))
+
+    @mock.patch('functest.cli.commands.cli_tier.click.echo')
+    def test_gettests_missing_tier(self, mock_click_echo):
+        with mock.patch.object(self.cli_tier.tiers, 'get_tier',
+                               return_value=None), \
+            mock.patch.object(self.cli_tier.tiers, 'get_tier_names',
+                              return_value='tiernames'):
+            self.cli_tier.gettests(self.tiername)
+            mock_click_echo.assert_called_with("The tier with name '%s' does "
+                                               "not exist. Available tiers are"
+                                               ":\n  %s\n" % (self.tiername,
+                                                              'tiernames'))
+
+    @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+                return_value=False)
+    @mock.patch('functest.cli.commands.cli_tier.click.echo')
+    def test_run_missing_env_file(self, mock_click_echo, mock_os):
+        self.cli_tier.run(self.tiername)
+        mock_click_echo.assert_called_with("Functest environment is not ready."
+                                           " Run first 'functest env prepare'")
+
+    @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+    def test_run_default(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/run_tests.py "
+               "%s -t %s" % (CONST.dir_repo_functest, "-n -r ",
+                             self.tiername))
+        self.cli_tier.run(self.tiername, noclean=True, report=True)
+        mock_ft_utils.assert_called_with(cmd)
+
+    @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+    def test_run_report_missing_noclean(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/run_tests.py "
+               "%s -t %s" % (CONST.dir_repo_functest, "-r ",
+                             self.tiername))
+        self.cli_tier.run(self.tiername, noclean=False, report=True)
+        mock_ft_utils.assert_called_with(cmd)
+
+    @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+    def test_run_noclean_missing_report(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/run_tests.py "
+               "%s -t %s" % (CONST.dir_repo_functest, "-n ",
+                             self.tiername))
+        self.cli_tier.run(self.tiername, noclean=True, report=False)
+        mock_ft_utils.assert_called_with(cmd)
+
+    @mock.patch('functest.cli.commands.cli_tier.os.path.isfile',
+                return_value=True)
+    @mock.patch('functest.cli.commands.cli_tier.ft_utils.execute_command')
+    def test_run_missing_noclean_report(self, mock_ft_utils, mock_os):
+        cmd = ("python %s/functest/ci/run_tests.py "
+               "%s -t %s" % (CONST.dir_repo_functest, "",
+                             self.tiername))
+        self.cli_tier.run(self.tiername, noclean=False, report=False)
+        mock_ft_utils.assert_called_with(cmd)
+
+
+if __name__ == "__main__":
+    unittest.main(verbosity=2)
diff --git a/functest/tests/unit/cli/test_cli_base.py b/functest/tests/unit/cli/test_cli_base.py
new file mode 100644 (file)
index 0000000..fe065c2
--- /dev/null
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2016 Orange and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+import logging
+import unittest
+
+import mock
+from click.testing import CliRunner
+
+with mock.patch('functest.cli.commands.cli_testcase.CliTestcase.__init__',
+                mock.Mock(return_value=None)), \
+    mock.patch('functest.cli.commands.cli_tier.CliTier.__init__',
+               mock.Mock(return_value=None)):
+    from functest.cli import cli_base
+
+
+class CliBaseTesting(unittest.TestCase):
+
+    logging.disable(logging.CRITICAL)
+
+    def setUp(self):
+        self.runner = CliRunner()
+        self._openstack = cli_base._openstack
+        self._env = cli_base._env
+        self._testcase = cli_base._testcase
+        self._tier = cli_base._tier
+
+    def test_os_check(self):
+        with mock.patch.object(self._openstack, 'check') as mock_method:
+            result = self.runner.invoke(cli_base.os_check)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_os_snapshot_create(self):
+        with mock.patch.object(self._openstack, 'snapshot_create') \
+                as mock_method:
+            result = self.runner.invoke(cli_base.os_snapshot_create)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_os_snapshot_show(self):
+        with mock.patch.object(self._openstack, 'snapshot_show') \
+                as mock_method:
+            result = self.runner.invoke(cli_base.os_snapshot_show)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_os_clean(self):
+        with mock.patch.object(self._openstack, 'clean') as mock_method:
+            result = self.runner.invoke(cli_base.os_clean)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_os_show_credentials(self):
+        with mock.patch.object(self._openstack, 'show_credentials') \
+                as mock_method:
+            result = self.runner.invoke(cli_base.os_show_credentials)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_os_fetch_rc(self):
+        with mock.patch.object(self._openstack, 'fetch_credentials') \
+                as mock_method:
+            result = self.runner.invoke(cli_base.os_fetch_rc)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_env_prepare(self):
+        with mock.patch.object(self._env, 'prepare') as mock_method:
+            result = self.runner.invoke(cli_base.env_prepare)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_env_show(self):
+        with mock.patch.object(self._env, 'show') as mock_method:
+            result = self.runner.invoke(cli_base.env_show)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_env_status(self):
+        with mock.patch.object(self._env, 'status') as mock_method:
+            result = self.runner.invoke(cli_base.env_status)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_testcase_list(self):
+        with mock.patch.object(self._testcase, 'list') as mock_method:
+            result = self.runner.invoke(cli_base.testcase_list)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_testcase_show(self):
+        with mock.patch.object(self._testcase, 'show') as mock_method:
+            result = self.runner.invoke(cli_base.testcase_show, ['testname'])
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_testcase_run(self):
+        with mock.patch.object(self._testcase, 'run') as mock_method:
+            result = self.runner.invoke(cli_base.testcase_run,
+                                        ['testname', '--noclean'])
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_tier_list(self):
+        with mock.patch.object(self._tier, 'list') as mock_method:
+            result = self.runner.invoke(cli_base.tier_list)
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_tier_show(self):
+        with mock.patch.object(self._tier, 'show') as mock_method:
+            result = self.runner.invoke(cli_base.tier_show, ['tiername'])
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_tier_gettests(self):
+        with mock.patch.object(self._tier, 'gettests') as mock_method:
+            result = self.runner.invoke(cli_base.tier_gettests, ['tiername'])
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+    def test_tier_run(self):
+        with mock.patch.object(self._tier, 'run') as mock_method:
+            result = self.runner.invoke(cli_base.tier_run,
+                                        ['tiername', '--noclean'])
+            self.assertEqual(result.exit_code, 0)
+            self.assertTrue(mock_method.called)
+
+
+if __name__ == "__main__":
+    unittest.main(verbosity=2)
index b7c81d8..b6efa40 100644 (file)
@@ -11,6 +11,7 @@ import logging
 import mock
 import unittest
 
+mock.patch('logging.FileHandler').start()  # noqa
 from functest.core import testcase_base
 
 
index d8c7f84..d45d562 100644 (file)
@@ -11,12 +11,15 @@ import errno
 import logging
 import mock
 import os
+import StringIO
 import unittest
 
 from keystoneauth1.exceptions import auth_plugins
-from robot.errors import RobotError
+from robot.errors import DataError, RobotError
 from robot.result import testcase
+from robot.utils.robottime import timestamp_to_secs
 
+mock.patch('logging.FileHandler').start()  # noqa
 from functest.core import testcase_base
 from functest.opnfv_tests.sdn.odl import odl
 
@@ -44,6 +47,17 @@ class ODLTesting(unittest.TestCase):
         os.environ["OS_PASSWORD"] = self._os_password
         os.environ["OS_TENANT_NAME"] = self._os_tenantname
         self.test = odl.ODLTests()
+        self.defaultargs = {'odlusername': self._odl_username,
+                            'odlpassword': self._odl_password,
+                            'keystoneip': self._keystone_ip,
+                            'neutronip': self._keystone_ip,
+                            'osusername': self._os_username,
+                            'ostenantname': self._os_tenantname,
+                            'ospassword': self._os_password,
+                            'odlip': self._keystone_ip,
+                            'odlwebport': self._odl_webport,
+                            'odlrestconfport': self._odl_restconfport,
+                            'pushtodb': False}
 
     def test_empty_visitor(self):
         visitor = odl.ODLResultVisitor()
@@ -72,14 +86,65 @@ class ODLTesting(unittest.TestCase):
         visitor.visit_test(test)
         self.assertEqual(visitor.get_data(), [data])
 
+    @mock.patch('robot.api.ExecutionResult', side_effect=DataError)
+    def test_parse_results_raises_exceptions(self, *args):
+        with self.assertRaises(DataError):
+            self.test.parse_results()
+
+    def test_parse_results(self, *args):
+        config = {'name': 'dummy', 'starttime': '20161216 16:00:00.000',
+                  'endtime': '20161216 16:00:01.000', 'status': 'PASS'}
+        suite = mock.Mock()
+        suite.configure_mock(**config)
+        with mock.patch('robot.api.ExecutionResult',
+                        return_value=mock.Mock(suite=suite)):
+            self.test.parse_results()
+            self.assertEqual(self.test.criteria, config['status'])
+            self.assertEqual(self.test.start_time,
+                             timestamp_to_secs(config['starttime']))
+            self.assertEqual(self.test.stop_time,
+                             timestamp_to_secs(config['endtime']))
+            self.assertEqual(self.test.details,
+                             {'description': config['name'], 'tests': []})
+
     @mock.patch('fileinput.input', side_effect=Exception())
     def test_set_robotframework_vars_failed(self, *args):
         self.assertFalse(self.test.set_robotframework_vars())
 
     @mock.patch('fileinput.input', return_value=[])
-    def test_set_robotframework_vars(self, args):
+    def test_set_robotframework_vars_empty(self, args):
         self.assertTrue(self.test.set_robotframework_vars())
 
+    @mock.patch('sys.stdout', new_callable=StringIO.StringIO)
+    def _test_set_robotframework_vars(self, msg1, msg2, *args):
+        line = mock.MagicMock()
+        line.__iter__.return_value = [msg1]
+        with mock.patch('fileinput.input', return_value=line) as mock_method:
+            self.assertTrue(self.test.set_robotframework_vars())
+            mock_method.assert_called_once_with(
+                os.path.join(odl.ODLTests.odl_test_repo,
+                             'csit/variables/Variables.py'), inplace=True)
+            self.assertEqual(args[0].getvalue(), "{}\n".format(msg2))
+
+    def test_set_robotframework_vars_auth_default(self):
+        self._test_set_robotframework_vars("AUTH = []",
+                                           "AUTH = [u'admin', u'admin']")
+
+    def test_set_robotframework_vars_auth1(self):
+        self._test_set_robotframework_vars("AUTH1 = []", "AUTH1 = []")
+
+    @mock.patch('sys.stdout', new_callable=StringIO.StringIO)
+    def test_set_robotframework_vars_auth_foo(self, *args):
+        line = mock.MagicMock()
+        line.__iter__.return_value = ["AUTH = []"]
+        with mock.patch('fileinput.input', return_value=line) as mock_method:
+            self.assertTrue(self.test.set_robotframework_vars('foo', 'bar'))
+            mock_method.assert_called_once_with(
+                os.path.join(odl.ODLTests.odl_test_repo,
+                             'csit/variables/Variables.py'), inplace=True)
+            self.assertEqual(args[0].getvalue(),
+                             "AUTH = [u'{}', u'{}']\n".format('foo', 'bar'))
+
     @classmethod
     def _fake_url_for(cls, service_type='identity', **kwargs):
         if service_type == 'identity':
@@ -194,6 +259,8 @@ class ODLTesting(unittest.TestCase):
     def test_main_robot_run_failed(self, *args):
         with mock.patch.object(self.test, 'set_robotframework_vars',
                                return_value=True), \
+                mock.patch.object(odl, 'open', mock.mock_open(),
+                                  create=True), \
                 self.assertRaises(RobotError):
             self._test_main(testcase_base.TestcaseBase.EX_RUN_ERROR, *args)
 
@@ -202,6 +269,8 @@ class ODLTesting(unittest.TestCase):
     def test_main_parse_results_failed(self, *args):
         with mock.patch.object(self.test, 'set_robotframework_vars',
                                return_value=True), \
+                mock.patch.object(odl, 'open', mock.mock_open(),
+                                  create=True), \
                 mock.patch.object(self.test, 'parse_results',
                                   side_effect=RobotError):
             self._test_main(testcase_base.TestcaseBase.EX_RUN_ERROR, *args)
@@ -222,6 +291,8 @@ class ODLTesting(unittest.TestCase):
     def test_main(self, *args):
         with mock.patch.object(self.test, 'set_robotframework_vars',
                                return_value=True), \
+                mock.patch.object(odl, 'open', mock.mock_open(),
+                                  create=True), \
                 mock.patch.object(self.test, 'parse_results'):
             self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
 
@@ -231,6 +302,8 @@ class ODLTesting(unittest.TestCase):
     def test_main_makedirs_oserror17(self, *args):
         with mock.patch.object(self.test, 'set_robotframework_vars',
                                return_value=True), \
+                mock.patch.object(odl, 'open', mock.mock_open(),
+                                  create=True), \
                 mock.patch.object(self.test, 'parse_results'):
             self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
 
@@ -240,6 +313,8 @@ class ODLTesting(unittest.TestCase):
     def test_main_testcases_in_failure(self, *args):
         with mock.patch.object(self.test, 'set_robotframework_vars',
                                return_value=True), \
+                mock.patch.object(odl, 'open', mock.mock_open(),
+                                  create=True), \
                 mock.patch.object(self.test, 'parse_results'):
             self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
 
@@ -249,6 +324,8 @@ class ODLTesting(unittest.TestCase):
     def test_main_remove_oserror(self, *args):
         with mock.patch.object(self.test, 'set_robotframework_vars',
                                return_value=True), \
+                mock.patch.object(odl, 'open', mock.mock_open(),
+                                  create=True), \
                 mock.patch.object(self.test, 'parse_results'):
             self._test_main(testcase_base.TestcaseBase.EX_OK, *args)
 
@@ -353,6 +430,77 @@ class ODLTesting(unittest.TestCase):
         self._test_run(testcase_base.TestcaseBase.EX_OK,
                        odlip=self._neutron_ip, odlwebport='8181')
 
+    def test_argparser_default(self):
+        parser = odl.ODLParser()
+        self.assertEqual(parser.parse_args(), self.defaultargs)
+
+    def test_argparser_basic(self):
+        self.defaultargs['neutronip'] = self._neutron_ip
+        self.defaultargs['odlip'] = self._sdn_controller_ip
+        parser = odl.ODLParser()
+        self.assertEqual(parser.parse_args(
+            ["--neutronip={}".format(self._neutron_ip),
+             "--odlip={}".format(self._sdn_controller_ip)
+             ]), self.defaultargs)
+
+    @mock.patch('sys.stderr', new_callable=StringIO.StringIO)
+    def test_argparser_fail(self, *args):
+        self.defaultargs['foo'] = 'bar'
+        parser = odl.ODLParser()
+        with self.assertRaises(SystemExit):
+            parser.parse_args(["--foo=bar"])
+
+    def _test_argparser(self, arg, value):
+        self.defaultargs[arg] = value
+        parser = odl.ODLParser()
+        self.assertEqual(parser.parse_args(["--{}={}".format(arg, value)]),
+                         self.defaultargs)
+
+    def test_argparser_odlusername(self):
+        self._test_argparser('odlusername', 'foo')
+
+    def test_argparser_odlpassword(self):
+        self._test_argparser('odlpassword', 'foo')
+
+    def test_argparser_keystoneip(self):
+        self._test_argparser('keystoneip', '127.0.0.4')
+
+    def test_argparser_neutronip(self):
+        self._test_argparser('neutronip', '127.0.0.4')
+
+    def test_argparser_osusername(self):
+        self._test_argparser('osusername', 'foo')
+
+    def test_argparser_ostenantname(self):
+        self._test_argparser('ostenantname', 'foo')
+
+    def test_argparser_ospassword(self):
+        self._test_argparser('ospassword', 'foo')
+
+    def test_argparser_odlip(self):
+        self._test_argparser('odlip', '127.0.0.4')
+
+    def test_argparser_odlwebport(self):
+        self._test_argparser('odlwebport', '80')
+
+    def test_argparser_odlrestconfport(self):
+        self._test_argparser('odlrestconfport', '80')
+
+    def test_argparser_pushtodb(self):
+        self.defaultargs['pushtodb'] = True
+        parser = odl.ODLParser()
+        self.assertEqual(parser.parse_args(["--{}".format('pushtodb')]),
+                         self.defaultargs)
+
+    def test_argparser_multiple_args(self):
+        self.defaultargs['neutronip'] = self._neutron_ip
+        self.defaultargs['odlip'] = self._sdn_controller_ip
+        parser = odl.ODLParser()
+        self.assertEqual(parser.parse_args(
+            ["--neutronip={}".format(self._neutron_ip),
+             "--odlip={}".format(self._sdn_controller_ip)
+             ]), self.defaultargs)
+
 
 if __name__ == "__main__":
     unittest.main(verbosity=2)
index ce9086a..c4b5666 100644 (file)
@@ -18,6 +18,7 @@ import mock
 import requests
 
 from functest.tests.unit import test_utils
+mock.patch('logging.FileHandler').start()  # noqa
 from functest.utils import functest_utils
 
 
index 0421730..79d05d3 100755 (executable)
@@ -2,32 +2,6 @@
 set -o errexit
 set -o pipefail
 
-function clean_results_dir {
-    if [ -d "/home/opnfv/functest/results" ]
-    then
-        sudo rm -rf /home/opnfv/functest/results
-    fi
-}
-
-# ******************************
-# prepare the env for the tests
-# ******************************
-# clean useless results dir
-# should be done at the end
-# but in case of crash during unit test
-# clean it anyway
-clean_results_dir
-
-# TODO clean that...
-# Create log dir if needed
-# log shall be disabled during unit tests
-# fix to be done in Logger
-echo "Create dummy log file...."
-sudo mkdir -p /home/opnfv/functest/results/odl
-sudo touch /home/opnfv/functest/results/functest.log
-sudo touch /home/opnfv/functest/results/odl/stdout.txt
-sudo chmod -Rf a+rw /home/opnfv
-
 # Either Workspace is set (CI)
 if [ -z $WORKSPACE ]
 then
@@ -58,6 +32,7 @@ nosetests --with-xunit \
          --with-coverage \
          --cover-erase \
          --cover-tests \
+         --cover-package=functest.cli \
          --cover-package=functest.core.testcase_base \
          --cover-package=functest.opnfv_tests.sdn.odl.odl \
          --cover-package=functest.utils \
@@ -68,10 +43,4 @@ rc=$?
 
 deactivate
 
-# *******
-# clean
-# *******
-# Clean useless logs
-clean_results_dir
-
 exit $rc
index 7b0a489..2bf297b 100755 (executable)
@@ -5,6 +5,7 @@
 # which accompanies this distribution, and is available at
 # http://www.apache.org/licenses/LICENSE-2.0
 #
+click==6.6
 coverage==4.1
 dnspython==1.15.0
 gitpython==1.0.1