dovetail tool: command line 97/26697/12
authorMatthewLi <matthew.lijun@huawei.com>
Thu, 5 Jan 2017 07:02:13 +0000 (02:02 -0500)
committerMatthewLi <matthew.lijun@huawei.com>
Fri, 13 Jan 2017 08:56:42 +0000 (03:56 -0500)
JIRA: DOVETAIL-173

details please see https://wiki.opnfv.org/display/dovetail/Dovetail+Command+Line

Change-Id: Iff04b0df8c4e6310d35a45b9c8ba3c7b3b5e1105
Signed-off-by: MatthewLi <matthew.lijun@huawei.com>
docker/Dockerfile
dovetail/cli/__init__.py [new file with mode: 0644]
dovetail/cli/cli_base.py [new file with mode: 0644]
dovetail/cli/commands/__init__.py [new file with mode: 0644]
dovetail/cli/commands/cli_report.py [new file with mode: 0644]
dovetail/cli/commands/cli_testcase.py [new file with mode: 0644]
dovetail/testcase.py
dovetail/utils/dovetail_logger.py
dovetail/utils/dovetail_utils.py
requirements.txt
setup.cfg

index 038993b..187fbc9 100644 (file)
@@ -18,7 +18,8 @@ RUN \
     pip install pbr \
         pyyaml \
         click \
-        jinja2
+        jinja2 \
+        six
 
 ENV HOME /home/opnfv
 ENV REPOS_DIR ${HOME}/dovetail
@@ -29,6 +30,10 @@ RUN \
 && \
     git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/dovetail.git ${REPOS_DIR} \
 && \
-    mkdir -p ${REPOS_DIR}/results
+    mkdir -p ${REPOS_DIR}/results \
+&& \
+    cd ${REPOS_DIR} \
+&& \
+    pip install .
 
 WORKDIR ${REPOS_DIR}/dovetail
diff --git a/dovetail/cli/__init__.py b/dovetail/cli/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dovetail/cli/cli_base.py b/dovetail/cli/cli_base.py
new file mode 100644 (file)
index 0000000..c0d57e8
--- /dev/null
@@ -0,0 +1,56 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd 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 click
+from pbr import version
+from dovetail.cli.commands.cli_testcase import CliTestcase
+
+
+CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
+cli_version = version.VersionInfo('dovetail').version_string()
+
+
+@click.group(context_settings=CONTEXT_SETTINGS)
+@click.version_option(version=cli_version)
+def cli():
+    pass
+
+
+_testcase = CliTestcase()
+
+
+@cli.command('list',
+             help='list the testsuite details')
+@click.argument('testsuite', type=click.STRING, required=False)
+def testcase_list(testsuite):
+    _testcase.list_testcase(testsuite)
+
+
+@cli.command('show',
+             help='show the testcases details')
+@click.argument('testcase', type=click.STRING, required=True)
+def testcase_show(testcase):
+    _testcase.show_testcase(testcase)
+
+
+@cli.command('run',
+             context_settings=dict(
+                 ignore_unknown_options=True, help_option_names=[]),
+             help='run the testcases')
+@click.argument('run_args', nargs=-1, type=click.UNPROCESSED)
+def testcase_run(run_args):
+    args_list = [] + list(run_args)
+    args_str = ' '.join(args_list)
+    _testcase.run(args_str)
+
+
+# @cli.command('report', help='testcases running result report')
+# @click.option('--encrypt', default=True,
+#               help='report the test result with encryption')
+# def run(**kwargs):
+#     CliReport.execute(**kwargs)
diff --git a/dovetail/cli/commands/__init__.py b/dovetail/cli/commands/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dovetail/cli/commands/cli_report.py b/dovetail/cli/commands/cli_report.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dovetail/cli/commands/cli_testcase.py b/dovetail/cli/commands/cli_testcase.py
new file mode 100644 (file)
index 0000000..b1c38fd
--- /dev/null
@@ -0,0 +1,107 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd 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 os
+import sys
+import yaml
+import click
+import six
+
+import dovetail.utils.dovetail_utils as dt_utils
+from dovetail.utils.dovetail_config import DovetailConfig as dt_cfg
+from dovetail.testcase import Testsuite
+
+
+class CliTestcase:
+
+    @classmethod
+    def testsuite_load(cls):
+        dt_cfg.load_config_files()
+        Testsuite.load()
+
+    @classmethod
+    def get_path(cls, path):
+        if isinstance(path, six.string_types):
+            dt_cfg.load_config_files()
+            dovetail_dir = os.path.abspath(
+                os.path.join(os.path.dirname(__file__),
+                             os.pardir, os.pardir))
+            relative_path = dt_cfg.dovetail_config[path]
+            abs_path = os.path.join(dovetail_dir, relative_path)
+        else:
+            click.echo("input %s is not a string" % path)
+            sys.exit(1)
+        return abs_path
+
+    def list_testcase(self, testsuite):
+        self.testsuite_load()
+        if testsuite:
+            testsuite_stream = Testsuite.get(testsuite)
+            if testsuite_stream:
+                testcase_list = []
+                for value in testsuite_stream['testcases_list']:
+                    if value is not None:
+                        testcase_list.append(value)
+                testarea_list = []
+                for testcase in testcase_list:
+                    testarea = testcase.split('.')[1]
+                    if testarea not in testarea_list:
+                        testarea_list.append(testarea)
+                for testarea in testarea_list:
+                    click.echo("- %s" % testarea)
+                    for testcase in testcase_list:
+                        if testarea in testcase:
+                            click.echo("    %s" % testcase)
+            else:
+                click.echo("testsuite %s does not exist or not supported"
+                           % testsuite)
+        else:
+            testsuite_json = Testsuite.get_all()
+            if testsuite_json:
+                for key, value in testsuite_json.items():
+                    click.echo("- %s" % key)
+                    testsuite_stream = Testsuite.get(key)
+                    if testsuite_stream['testcases_list']:
+                        for testcase in testsuite_stream['testcases_list']:
+                            click.echo("    %s" % testcase)
+                    else:
+                        click.echo("No testcase in testsuite %s" % key)
+            else:
+                click.echo("No testsuite defined yet in dovetail!!!")
+
+    def show_testcase(self, testcase):
+        abs_testcase_path = self.get_path('TESTCASE_PATH')
+        if testcase.startswith("dovetail."):
+            testcase_yml = testcase[9:] + '.yml'
+        else:
+            testcase_yml = testcase + '.yml'
+        for root, dirs, files in os.walk(abs_testcase_path):
+            if testcase_yml in files:
+                testcase_path = abs_testcase_path + testcase_yml
+                with open(testcase_path, 'r') as stream:
+                    try:
+                        click.echo(stream.read())
+                    except yaml.YAMLError as exc:
+                        click.echo(exc)
+            else:
+                click.echo("testcase %s does not exist or not supported"
+                           % testcase)
+
+    def run(self, args_str):
+        options = ''
+        if args_str:
+            options = options + args_str
+
+        repo_dir = os.path.abspath(
+            os.path.join(os.path.dirname(__file__),
+                         os.pardir, os.pardir))
+
+        cmd = ("python %s/run.py"
+               " %s" % (repo_dir, options))
+        dt_utils.exec_cmd(cmd, exit_on_error=False,
+                          exec_msg_on=False, info=True)
index 47b0f07..ed7b832 100644 (file)
@@ -279,10 +279,14 @@ class Testsuite:
                     testsuite_yaml = yaml.safe_load(f)
                     cls.testsuite_list.update(testsuite_yaml)
 
-        cls.logger.debug(cls.testsuite_list)
+        cls.logger.debug(cls.testsuite_list)
 
     @classmethod
     def get(cls, testsuite_name):
         if testsuite_name in cls.testsuite_list:
             return cls.testsuite_list[testsuite_name]
         return None
+
+    @classmethod
+    def get_all(cls):
+        return cls.testsuite_list
index 685db8f..0fe4103 100644 (file)
@@ -23,6 +23,7 @@
 
 import logging
 import os
+import sys
 
 from dovetail_config import DovetailConfig as dt_cfg
 
@@ -36,7 +37,7 @@ class Logger:
         self.logger.propagate = 0
         self.logger.setLevel(logging.DEBUG)
 
-        ch = logging.StreamHandler()
+        ch = logging.StreamHandler(sys.stdout)
         formatter = logging.Formatter('%(asctime)s - %(name)s - '
                                       '%(levelname)s - %(message)s')
         ch.setFormatter(formatter)
index 8c4865d..960801a 100644 (file)
@@ -35,11 +35,12 @@ def exec_log(verbose, logger, msg, level, flush=False):
 
 
 def exec_cmd(cmd, logger=None, exit_on_error=False, info=False,
-             err_msg="", verbose=True):
+             exec_msg_on=True, err_msg="", verbose=True):
     msg_err = ("The command '%s' failed." % cmd) if not err_msg else err_msg
     msg_exec = ("Executing command: '%s'" % cmd)
     level = 'info' if info else 'debug'
-    exec_log(verbose, logger, msg_exec, level)
+    if exec_msg_on:
+        exec_log(verbose, logger, msg_exec, level)
 
     p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE)
index 502fb37..8c4577c 100644 (file)
@@ -1,4 +1,5 @@
 pbr>=1.8
 Jinja2>=2.6
 PyYAML>=3.10
+six>=1.9.0
 Click
index de8b27f..4908f19 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,8 +1,8 @@
 [metadata]
 name = dovetail
-version = 0.1
+version = 0.1.0
 home-page = https://wiki.opnfv.org/display/dovetail
 
 [entry_points]
 console_scripts =
-    dovetail = dovetail.run:main
+    dovetail = dovetail.cli.cli_base:cli