diff options
-rw-r--r-- | api/actions/test.py | 14 | ||||
-rw-r--r-- | api/server.py | 3 | ||||
-rw-r--r-- | api/utils/common.py | 7 | ||||
-rw-r--r-- | docker/Dockerfile | 2 | ||||
-rw-r--r-- | tests/unit/api/actions/test_env.py | 50 | ||||
-rw-r--r-- | tests/unit/api/actions/test_result.py | 29 | ||||
-rw-r--r-- | tests/unit/api/actions/test_test.py | 29 | ||||
-rw-r--r-- | tests/unit/api/test_views.py | 57 | ||||
-rw-r--r-- | tests/unit/api/utils/test_common.py | 30 | ||||
-rw-r--r-- | tests/unit/api/utils/test_daemonthread.py | 37 | ||||
-rw-r--r-- | yardstick/__init__.py | 38 | ||||
-rwxr-xr-x | yardstick/benchmark/scenarios/networking/netperf_benchmark.bash | 45 | ||||
-rwxr-xr-x | yardstick/benchmark/scenarios/networking/netperf_install.bash | 8 | ||||
-rwxr-xr-x | yardstick/benchmark/scenarios/networking/netperf_node.py | 27 | ||||
-rw-r--r-- | yardstick/cmd/cli.py | 10 | ||||
-rw-r--r-- | yardstick/dispatcher/file.py | 1 | ||||
-rw-r--r-- | yardstick/ssh.py | 25 |
17 files changed, 122 insertions, 290 deletions
diff --git a/api/actions/test.py b/api/actions/test.py index b1dc212c2..fda0ffd32 100644 --- a/api/actions/test.py +++ b/api/actions/test.py @@ -7,7 +7,6 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## import uuid -import json import os import logging @@ -22,12 +21,7 @@ def runTestCase(args): opts = args.get('opts', {}) testcase = args['testcase'] except KeyError: - logger.error('Lack of testcase argument') - result = { - 'status': 'error', - 'message': 'need testcase name' - } - return json.dumps(result) + return common_utils.error_handler('Lack of testcase argument') testcase = os.path.join(conf.TEST_CASE_PATH, conf.TEST_CASE_PRE + testcase + '.yaml') @@ -41,8 +35,4 @@ def runTestCase(args): logger.debug('Start to execute command list') common_utils.exec_command_task(command_list, task_id) - result = { - 'status': 'success', - 'task_id': task_id - } - return json.dumps(result) + return common_utils.result_handler('success', task_id) diff --git a/api/server.py b/api/server.py index 1cbe1725d..3f104c61a 100644 --- a/api/server.py +++ b/api/server.py @@ -12,6 +12,7 @@ from flask import Flask from flask_restful import Api from api.urls import urlpatterns +from yardstick import _init_logging logger = logging.getLogger(__name__) @@ -23,5 +24,7 @@ reduce(lambda a, b: a.add_resource(b.resource, b.url, endpoint=b.endpoint) or a, urlpatterns, api) if __name__ == '__main__': + _init_logging() + logger.setLevel(logging.DEBUG) logger.info('Starting server') app.run(host='0.0.0.0') diff --git a/api/utils/common.py b/api/utils/common.py index 09cfc04d4..e3e64a72b 100644 --- a/api/utils/common.py +++ b/api/utils/common.py @@ -8,7 +8,8 @@ ############################################################################## import collections import logging -import json + +from flask import jsonify from api.utils.daemonthread import DaemonThread from yardstick.cmd.cli import YardstickCLI @@ -50,7 +51,7 @@ def error_handler(message): 'status': 'error', 'message': message } - return json.dumps(result) + return jsonify(result) def result_handler(status, data): @@ -58,7 +59,7 @@ def result_handler(status, data): 'status': status, 'result': data } - return json.dumps(result) + return jsonify(result) class Url(object): diff --git a/docker/Dockerfile b/docker/Dockerfile index 36db2bb13..fb8625e50 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,6 +11,8 @@ FROM ubuntu:14.04 LABEL image=opnfv/yardstick +ARG BRANCH=master + # GIT repo directory ENV REPOS_DIR /home/opnfv/repos diff --git a/tests/unit/api/actions/test_env.py b/tests/unit/api/actions/test_env.py deleted file mode 100644 index e674d73d2..000000000 --- a/tests/unit/api/actions/test_env.py +++ /dev/null @@ -1,50 +0,0 @@ -############################################################################## -# 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 unittest -import mock - -from api.actions import env - - -class CreateInfluxDBContainerTestCase(unittest.TestCase): - - @mock.patch('api.actions.env._create_influxdb_container') - def test_create_influxdb_container(self, mock_create_container): - env.createInfluxDBContainer({}) - mock_create_container.assert_called_with() - - -class CreateInfluxdbContainerTestCase(unittest.TestCase): - - @mock.patch('api.actions.env.Client') - def test_create_influxdb_container(self, mock_influx_client): - env._create_influxdb_container() - self.assertFalse(mock_influx_client()._create_container.called) - - -class ConfigInfluxdbTestCase(unittest.TestCase): - - @mock.patch('api.actions.env.influx.get_data_db_client') - def test_config_influxdb(self, mock_influx_client): - env._config_influxdb() - mock_influx_client.assert_called_with() - - -class ConfigOutputFile(unittest.TestCase): - - def test_config_output_file(self): - pass - - -def main(): - unittest.main() - - -if __name__ == '__main__': - main() diff --git a/tests/unit/api/actions/test_result.py b/tests/unit/api/actions/test_result.py deleted file mode 100644 index 168631905..000000000 --- a/tests/unit/api/actions/test_result.py +++ /dev/null @@ -1,29 +0,0 @@ -############################################################################## -# 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 unittest -import json - -from api.actions import result - - -class GetResultTestCase(unittest.TestCase): - - def test_getResult_with_no_taskid_arg(self): - args = {} - output = json.loads(result.getResult(args)) - - self.assertEqual('error', output['status']) - - -def main(): - unittest.main() - - -if __name__ == '__main__': - main() diff --git a/tests/unit/api/actions/test_test.py b/tests/unit/api/actions/test_test.py deleted file mode 100644 index 7ebe9fc24..000000000 --- a/tests/unit/api/actions/test_test.py +++ /dev/null @@ -1,29 +0,0 @@ -############################################################################## -# 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 unittest -import json - -from api.actions import test - - -class RunTestCase(unittest.TestCase): - - def test_runTestCase_with_no_testcase_arg(self): - args = {} - output = json.loads(test.runTestCase(args)) - - self.assertEqual('error', output['status']) - - -def main(): - unittest.main() - - -if __name__ == '__main__': - main() diff --git a/tests/unit/api/test_views.py b/tests/unit/api/test_views.py deleted file mode 100644 index b83556713..000000000 --- a/tests/unit/api/test_views.py +++ /dev/null @@ -1,57 +0,0 @@ -############################################################################## -# 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 unittest -import mock -import json - -from api.views import Test -from api.views import Result -from api.views import Env - - -class TestTestCase(unittest.TestCase): - - @mock.patch('api.views.request') - def test_post(self, mock_request): - mock_request.json.get.side_effect = ['hello', {}] - - result = json.loads(Test().post()) - - self.assertEqual('error', result['status']) - - -class ResultTestCase(unittest.TestCase): - - @mock.patch('api.views.request') - def test_get(self, mock_request): - mock_request.args.get.return_value = 'hello' - - print Result().get() - result = json.loads(Result().get()) - - self.assertEqual('error', result['status']) - - -class EnvTestCase(unittest.TestCase): - - @mock.patch('api.views.request') - def test_post(self, mock_request): - mock_request.json.get.side_effect = ['hello', {}] - - result = json.loads(Env().post()) - - self.assertEqual('error', result['status']) - - -def main(): - unittest.main() - - -if __name__ == '__main__': - main() diff --git a/tests/unit/api/utils/test_common.py b/tests/unit/api/utils/test_common.py index 9e050c714..5d177409e 100644 --- a/tests/unit/api/utils/test_common.py +++ b/tests/unit/api/utils/test_common.py @@ -7,7 +7,6 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## import unittest -import json from api.utils import common @@ -58,35 +57,6 @@ class GetCommandListTestCase(unittest.TestCase): self.assertEqual(result_list, output_list) -class ErrorHandlerTestCase(unittest.TestCase): - - def test_error_handler(self): - message = 'hello world' - output_dict = json.loads(common.error_handler(message)) - - result = { - 'status': 'error', - 'message': message - } - - self.assertEqual(result, output_dict) - - -class ResultHandlerTestCase(unittest.TestCase): - - def test_result_handler(self): - status = 1 - data = ['hello world'] - output_dict = json.loads(common.result_handler(status, data)) - - result = { - 'status': status, - 'result': data - } - - self.assertEqual(result, output_dict) - - def main(): unittest.main() diff --git a/tests/unit/api/utils/test_daemonthread.py b/tests/unit/api/utils/test_daemonthread.py deleted file mode 100644 index f07f0fede..000000000 --- a/tests/unit/api/utils/test_daemonthread.py +++ /dev/null @@ -1,37 +0,0 @@ -############################################################################## -# 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 unittest -import mock - -from api.utils.daemonthread import DaemonThread - - -class DaemonThreadTestCase(unittest.TestCase): - - @mock.patch('api.utils.daemonthread.os') - def test_run(self, mock_os): - def func(common_list, task_id): - return task_id - - common_list = [] - task_id = '1234' - thread = DaemonThread(func, (common_list, task_id)) - thread.run() - - mock_os.path.exist.return_value = True - pre_path = '../tests/opnfv/test_suites/' - mock_os.remove.assert_called_with(pre_path + '1234.yaml') - - -def main(): - unittest.main() - - -if __name__ == '__main__': - main() diff --git a/yardstick/__init__.py b/yardstick/__init__.py index c31948d43..5c279c800 100644 --- a/yardstick/__init__.py +++ b/yardstick/__init__.py @@ -8,18 +8,40 @@ ############################################################################## import logging -import logging.config -import sys import os +import sys + import yardstick.vTC.apexlake as apexlake # Hack to be able to run apexlake unit tests # without having to install apexlake. sys.path.append(os.path.dirname(apexlake.__file__)) -logging.basicConfig( - level=logging.WARNING, - format='[%(asctime)s] %(name)-20s %(filename)s:%(lineno)d ' - '%(levelname)s %(message)s', # noqa - datefmt='%m/%d/%y %H:%M:%S') -logging.getLogger(__name__).setLevel(logging.INFO) +LOG_FILE = '/tmp/yardstick.log' +LOG_FORMATTER = ('%(asctime)s ' + '%(name)s %(filename)s:%(lineno)d ' + '%(levelname)s %(message)s') + +_LOG_FORMATTER = logging.Formatter(LOG_FORMATTER) +_LOG_STREAM_HDLR = logging.StreamHandler() +_LOG_FILE_HDLR = logging.FileHandler(LOG_FILE) + +LOG = logging.getLogger(__name__) + + +def _init_logging(): + + _LOG_STREAM_HDLR.setFormatter(_LOG_FORMATTER) + + # don't append to log file, clobber + _LOG_FILE_HDLR.setFormatter(_LOG_FORMATTER) + + del logging.root.handlers[:] + logging.root.addHandler(_LOG_STREAM_HDLR) + logging.root.addHandler(_LOG_FILE_HDLR) + logging.debug("logging.root.handlers = %s", logging.root.handlers) + + if os.environ.get('CI_DEBUG', '').lower() in {'1', 1, 'y', "yes", "true"}: + LOG.setLevel(logging.DEBUG) + else: + LOG.setLevel(logging.INFO) diff --git a/yardstick/benchmark/scenarios/networking/netperf_benchmark.bash b/yardstick/benchmark/scenarios/networking/netperf_benchmark.bash index a425c5df0..f6245c9cd 100755 --- a/yardstick/benchmark/scenarios/networking/netperf_benchmark.bash +++ b/yardstick/benchmark/scenarios/networking/netperf_benchmark.bash @@ -12,6 +12,7 @@ set -e # Commandline arguments +OPTIONS_SIZE="$#" OPTIONS="$@" OUTPUT_FILE=/tmp/netperf-out.log @@ -24,14 +25,40 @@ run_netperf() # write the result to stdout in json format output_json() { - mean=$(awk '/\/s/{print $3}' $OUTPUT_FILE) - troughput=$(awk '/\/s/{print $1}' $OUTPUT_FILE) - unit=$(awk '/\/s/{print $2}' $OUTPUT_FILE) - echo -e "{ \ - \"mean_latency\":\"$mean\", \ - \"troughput\":\"$troughput\", \ - \"troughput_unit\":\"$unit\" \ - }" + #ARR=($OPTIONS) + #declare -p ARR + read -r -a ARR <<< "$OPTIONS" + opt_size=0 + while [ $opt_size -lt "$OPTIONS_SIZE" ] + do + if [ "${ARR[$opt_size]}" = "-O" ] + then + break + fi + opt_size=$((opt_size+1)) + done + opt_size=$((opt_size+1)) + out_opt="${ARR[$opt_size]}" + IFS=, read -r -a PARTS <<< "$out_opt" + #declare -p PARTS + part_num=${#PARTS[*]} + tran_num=0 + for f in "${PARTS[@]}" + do + array_name[$tran_num]=$(echo "$f" | tr '[A-Z]' '[a-z]') + tran_num=$((tran_num+1)) + done + read -r -a DATA_PARTS <<< "$(sed -n '$p' $OUTPUT_FILE)" + out_str="{" + for((i=0;i<part_num-1;i++)) + do + modify_str=\"${array_name[i]}\":\"${DATA_PARTS[i]}\", + out_str=$out_str$modify_str + done + modify_str=\"${array_name[part_num-1]}\":\"${DATA_PARTS[part_num-1]}\" + out_str=$out_str$modify_str"}" + + echo -e "$out_str" } # main entry @@ -44,4 +71,4 @@ main() output_json } -main
\ No newline at end of file +main diff --git a/yardstick/benchmark/scenarios/networking/netperf_install.bash b/yardstick/benchmark/scenarios/networking/netperf_install.bash index eaa9f530a..0e3808f9c 100755 --- a/yardstick/benchmark/scenarios/networking/netperf_install.bash +++ b/yardstick/benchmark/scenarios/networking/netperf_install.bash @@ -11,6 +11,13 @@ set -e +svc="netserver" +if pgrep $svc >/dev/null +then + echo "$svc have existed, exit!" + exit 0 +fi + echo "===Install netperf before test begin!!!===" cp /etc/apt/sources.list /etc/apt/sources.list_bkp cp /etc/resolv.conf /etc/resolv.conf_bkp @@ -30,3 +37,4 @@ sudo apt-get install -y netperf service netperf start echo "===Install netperf before test end!!!===" + diff --git a/yardstick/benchmark/scenarios/networking/netperf_node.py b/yardstick/benchmark/scenarios/networking/netperf_node.py index 1578da7d8..a76982b6f 100755 --- a/yardstick/benchmark/scenarios/networking/netperf_node.py +++ b/yardstick/benchmark/scenarios/networking/netperf_node.py @@ -86,9 +86,8 @@ class NetperfNode(base.Scenario): self.client.wait(timeout=600) # copy script to host - self.client.run("cat > ~/netperf.sh", - stdin=open(self.target_script, "rb")) - + with open(self.target_script, "rb") as file_run: + self.client.run("cat > ~/netperf.sh", stdin=file_run) # copy script to host and client self.install_script = pkg_resources.resource_filename( 'yardstick.benchmark.scenarios.networking', @@ -97,14 +96,14 @@ class NetperfNode(base.Scenario): 'yardstick.benchmark.scenarios.networking', NetperfNode.REMOVE_SCRIPT) - self.server.run("cat > ~/netperf_install.sh", - stdin=open(self.install_script, "rb")) - self.client.run("cat > ~/netperf_install.sh", - stdin=open(self.install_script, "rb")) - self.server.run("cat > ~/netperf_remove.sh", - stdin=open(self.remove_script, "rb")) - self.client.run("cat > ~/netperf_remove.sh", - stdin=open(self.remove_script, "rb")) + with open(self.install_script, "rb") as file_install: + self.server.run("cat > ~/netperf_install.sh", stdin=file_install) + with open(self.install_script, "rb") as file_install: + self.client.run("cat > ~/netperf_install.sh", stdin=file_install) + with open(self.remove_script, "rb") as file_remove: + self.server.run("cat > ~/netperf_remove.sh", stdin=file_remove) + with open(self.remove_script, "rb") as file_remove: + self.client.run("cat > ~/netperf_remove.sh", stdin=file_remove) self.server.execute("sudo bash netperf_install.sh") self.client.execute("sudo bash netperf_install.sh") @@ -131,10 +130,12 @@ class NetperfNode(base.Scenario): else: testlen = 20 - cmd_args = "-H %s -l %s -t %s" % (ipaddr, testlen, testname) + cmd_args = "-H %s -l %s -t %s -c -C" % (ipaddr, testlen, testname) # get test specific options - default_args = "-O 'THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY'" + output_opt = options.get( + "output_opt", "THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY") + default_args = "-O %s" % output_opt cmd_args += " -- %s" % default_args option_pair_list = [("send_msg_size", "-m"), ("recv_msg_size", "-M"), diff --git a/yardstick/cmd/cli.py b/yardstick/cmd/cli.py index d141731e1..cac3dc5bf 100644 --- a/yardstick/cmd/cli.py +++ b/yardstick/cmd/cli.py @@ -19,6 +19,7 @@ from pkg_resources import get_distribution from argparse import RawDescriptionHelpFormatter from oslo_config import cfg +from yardstick import _init_logging, LOG from yardstick.cmd.commands import task from yardstick.cmd.commands import runner from yardstick.cmd.commands import scenario @@ -129,15 +130,12 @@ class YardstickCLI(): def _handle_global_opts(self): - # handle global opts - logger = logging.getLogger('yardstick') - logger.setLevel(logging.WARNING) - + _init_logging() if CONF.verbose: - logger.setLevel(logging.INFO) + LOG.setLevel(logging.INFO) if CONF.debug: - logger.setLevel(logging.DEBUG) + LOG.setLevel(logging.DEBUG) def _dispath_func_notask(self): diff --git a/yardstick/dispatcher/file.py b/yardstick/dispatcher/file.py index ab67796e9..c2cc265ba 100644 --- a/yardstick/dispatcher/file.py +++ b/yardstick/dispatcher/file.py @@ -17,6 +17,7 @@ # ceilometer/ceilometer/dispatcher/file.py import logging +import logging.handlers import json from oslo_config import cfg diff --git a/yardstick/ssh.py b/yardstick/ssh.py index 8b71fe606..d287b4dac 100644 --- a/yardstick/ssh.py +++ b/yardstick/ssh.py @@ -57,17 +57,16 @@ Eventlet: sshclient = eventlet.import_patched("opentstack.common.sshclient") """ - +import os import select import socket import time +import logging import paramiko from scp import SCPClient import six -import logging -LOG = logging.getLogger(__name__) DEFAULT_PORT = 22 @@ -84,7 +83,7 @@ class SSH(object): """Represent ssh connection.""" def __init__(self, user, host, port=DEFAULT_PORT, pkey=None, - key_filename=None, password=None): + key_filename=None, password=None, name=None): """Initialize SSH client. :param user: ssh username @@ -94,6 +93,11 @@ class SSH(object): :param key_filename: private key filename :param password: password """ + self.name = name + if name: + self.log = logging.getLogger(__name__ + '.' + self.name) + else: + self.log = logging.getLogger(__name__) self.user = user self.host = host @@ -103,6 +107,13 @@ class SSH(object): self.password = password self.key_filename = key_filename self._client = False + # paramiko loglevel debug will output ssh protocl debug + # we don't ever really want that unless we are debugging paramiko + # ssh issues + if os.environ.get("PARAMIKO_DEBUG", "").lower() == "true": + logging.getLogger("paramiko").setLevel(logging.DEBUG) + else: + logging.getLogger("paramiko").setLevel(logging.WARN) def _get_pkey(self, key): if isinstance(key, six.string_types): @@ -186,14 +197,14 @@ class SSH(object): if session.recv_ready(): data = session.recv(4096) - LOG.debug("stdout: %r" % data) + self.log.debug("stdout: %r" % data) if stdout is not None: stdout.write(data) continue if session.recv_stderr_ready(): stderr_data = session.recv_stderr(4096) - LOG.debug("stderr: %r" % stderr_data) + self.log.debug("stderr: %r" % stderr_data) if stderr is not None: stderr.write(stderr_data) continue @@ -256,7 +267,7 @@ class SSH(object): try: return self.execute("uname") except (socket.error, SSHError) as e: - LOG.debug("Ssh is still unavailable: %r" % e) + self.log.debug("Ssh is still unavailable: %r" % e) time.sleep(interval) if time.time() > (start_time + timeout): raise SSHTimeout("Timeout waiting for '%s'" % self.host) |