aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.rst70
-rw-r--r--api/__init__.py0
-rwxr-xr-xapi/api-prepare.sh55
-rw-r--r--api/base.py55
-rw-r--r--api/conf.py27
-rw-r--r--api/database/__init__.py29
-rw-r--r--api/database/models.py25
-rw-r--r--api/resources/__init__.py0
-rw-r--r--api/resources/env_action.py259
-rw-r--r--api/resources/release_action.py38
-rw-r--r--api/resources/results.py67
-rw-r--r--api/resources/samples_action.py37
-rw-r--r--api/server.py43
-rw-r--r--api/swagger/__init__.py0
-rw-r--r--api/swagger/docs/results.yaml41
-rw-r--r--api/swagger/docs/testcases.yaml50
-rw-r--r--api/swagger/models.py51
-rw-r--r--api/urls.py18
-rw-r--r--api/utils/__init__.py0
-rw-r--r--api/utils/common.py71
-rw-r--r--api/utils/daemonthread.py44
-rw-r--r--api/utils/influx.py73
-rw-r--r--api/views.py49
-rw-r--r--api/yardstick.ini16
-rw-r--r--dashboard/ping_dashboard.json1
-rw-r--r--docker/Dockerfile17
-rw-r--r--docs/release/release-notes.rst44
-rw-r--r--docs/userguide/07-installation.rst4
-rw-r--r--etc/yardstick/yardstick.conf.sample25
-rwxr-xr-xinstall.sh4
-rw-r--r--requirements.txt26
-rw-r--r--samples/background-task.yaml2
-rw-r--r--samples/cachestat.yaml2
-rw-r--r--samples/cyclictest.yaml2
-rw-r--r--samples/fio-template.yaml2
-rw-r--r--samples/fio.yaml2
-rw-r--r--samples/iperf3-jitter.yaml2
-rw-r--r--samples/iperf3.yaml2
-rw-r--r--samples/lmbench.yaml2
-rw-r--r--samples/lmbench_cache.yaml2
-rw-r--r--samples/memload.yaml2
-rwxr-xr-xsamples/netperf.yaml2
-rw-r--r--samples/netperf_bottlenecks.yaml43
-rw-r--r--samples/netutilization.yaml2
-rw-r--r--samples/perf.yaml2
-rw-r--r--samples/ping-ext-ip.yaml2
-rw-r--r--samples/ping-ext-stimuli.yaml2
-rw-r--r--samples/ping-heat-context.yaml2
-rw-r--r--samples/ping-hot.yaml2
-rwxr-xr-xsamples/ping-iteration.yaml2
-rw-r--r--samples/ping-multiple-context.yaml4
-rw-r--r--samples/ping-multiple-vm.yaml2
-rw-r--r--samples/ping-option-list.yaml2
-rw-r--r--samples/ping-parallel.yaml2
-rw-r--r--samples/ping-serial.yaml2
-rw-r--r--samples/ping-template.yaml2
-rw-r--r--samples/ping.yaml2
-rw-r--r--samples/pktgen.yaml2
-rw-r--r--samples/ramspeed.yaml2
-rw-r--r--samples/unixbench.yaml2
-rwxr-xr-xsetup.py6
-rwxr-xr-xtests/ci/clean_images.sh15
-rwxr-xr-xtests/ci/load_images.sh63
-rwxr-xr-xtests/ci/prepare_env.sh10
-rwxr-xr-xtests/ci/prepare_storperf_admin-rc.sh5
-rw-r--r--tests/ci/requirements.txt79
-rw-r--r--tests/ci/scp_storperf_admin-rc.sh11
-rwxr-xr-xtests/ci/yardstick-verify12
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml4
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml4
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml4
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml4
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml2
-rw-r--r--tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml2
-rw-r--r--tests/opnfv/test_suites/opnfv_components.yaml16
-rw-r--r--tests/opnfv/test_suites/opnfv_features.yaml52
-rw-r--r--tests/opnfv/test_suites/opnfv_performance.yaml62
-rw-r--r--tests/opnfv/test_suites/opnfv_smoke.yaml14
-rw-r--r--tests/unit/api/utils/test_common.py65
-rw-r--r--tests/unit/api/utils/test_influx.py82
-rw-r--r--tests/unit/benchmark/scenarios/networking/test_vsperf.py10
-rw-r--r--tests/unit/benchmark/scenarios/storage/test_storperf.py4
-rw-r--r--tests/unit/cmd/commands/test_env.py29
-rw-r--r--tests/unit/common/test_httpClient.py33
-rw-r--r--tests/unit/common/test_openstack_utils.py41
-rw-r--r--tests/unit/test_ssh.py105
-rwxr-xr-xtools/yardstick-img-lxd-modify7
-rwxr-xr-xtools/yardstick-img-modify13
-rw-r--r--yardstick/__init__.py38
-rw-r--r--yardstick/benchmark/contexts/node.py6
-rwxr-xr-xyardstick/benchmark/runners/arithmetic.py6
-rwxr-xr-xyardstick/benchmark/runners/base.py18
-rw-r--r--yardstick/benchmark/runners/duration.py6
-rw-r--r--yardstick/benchmark/runners/iteration.py6
-rw-r--r--yardstick/benchmark/runners/sequence.py6
-rw-r--r--yardstick/benchmark/scenarios/availability/actionrollbackers.py8
-rw-r--r--yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py32
-rw-r--r--yardstick/benchmark/scenarios/availability/attacker/attacker_general.py34
-rw-r--r--yardstick/benchmark/scenarios/availability/attacker/attacker_process.py27
-rw-r--r--yardstick/benchmark/scenarios/availability/attacker/baseattacker.py2
-rw-r--r--yardstick/benchmark/scenarios/availability/director.py6
-rw-r--r--yardstick/benchmark/scenarios/availability/monitor/basemonitor.py6
-rw-r--r--yardstick/benchmark/scenarios/availability/monitor/monitor_command.py17
-rw-r--r--yardstick/benchmark/scenarios/availability/monitor/monitor_general.py18
-rw-r--r--yardstick/benchmark/scenarios/availability/monitor/monitor_process.py13
-rw-r--r--yardstick/benchmark/scenarios/availability/operation/baseoperation.py2
-rw-r--r--yardstick/benchmark/scenarios/availability/operation/operation_general.py34
-rw-r--r--yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py2
-rw-r--r--yardstick/benchmark/scenarios/availability/result_checker/result_checker_general.py22
-rw-r--r--yardstick/benchmark/scenarios/availability/scenario_general.py2
-rwxr-xr-xyardstick/benchmark/scenarios/availability/serviceha.py4
-rw-r--r--yardstick/benchmark/scenarios/compute/cachestat.py5
-rw-r--r--yardstick/benchmark/scenarios/compute/computecapacity.py3
-rw-r--r--yardstick/benchmark/scenarios/compute/cpuload.py2
-rw-r--r--yardstick/benchmark/scenarios/compute/cyclictest.py18
-rw-r--r--yardstick/benchmark/scenarios/compute/lmbench.py12
-rw-r--r--yardstick/benchmark/scenarios/compute/memload.py2
-rw-r--r--yardstick/benchmark/scenarios/compute/perf.py3
-rw-r--r--yardstick/benchmark/scenarios/compute/ramspeed.py8
-rw-r--r--yardstick/benchmark/scenarios/compute/unixbench.py4
-rwxr-xr-xyardstick/benchmark/scenarios/networking/netperf.py3
-rwxr-xr-xyardstick/benchmark/scenarios/networking/netperf_benchmark.bash45
-rwxr-xr-xyardstick/benchmark/scenarios/networking/netperf_install.bash8
-rwxr-xr-xyardstick/benchmark/scenarios/networking/netperf_node.py27
-rw-r--r--yardstick/benchmark/scenarios/networking/netutilization.py2
-rw-r--r--yardstick/benchmark/scenarios/networking/networkcapacity.py3
-rw-r--r--yardstick/benchmark/scenarios/networking/ping.py9
-rw-r--r--yardstick/benchmark/scenarios/networking/ping6.py33
-rw-r--r--yardstick/benchmark/scenarios/networking/pktgen.py3
-rw-r--r--yardstick/benchmark/scenarios/networking/pktgen_dpdk.py9
-rw-r--r--yardstick/benchmark/scenarios/networking/sfc.py3
-rw-r--r--yardstick/benchmark/scenarios/networking/vsperf.py63
-rw-r--r--yardstick/benchmark/scenarios/storage/fio.py3
-rw-r--r--yardstick/benchmark/scenarios/storage/storagecapacity.py5
-rw-r--r--yardstick/benchmark/scenarios/storage/storperf.py69
-rw-r--r--yardstick/cmd/cli.py55
-rw-r--r--yardstick/cmd/commands/env.py39
-rw-r--r--yardstick/cmd/commands/task.py23
-rw-r--r--yardstick/common/constants.py55
-rw-r--r--yardstick/common/httpClient.py30
-rw-r--r--yardstick/common/openstack_utils.py97
-rw-r--r--yardstick/common/utils.py50
-rw-r--r--yardstick/dispatcher/file.py1
-rw-r--r--yardstick/dispatcher/http.py4
-rw-r--r--yardstick/dispatcher/influxdb.py8
-rw-r--r--yardstick/orchestrator/heat.py31
-rw-r--r--yardstick/ssh.py122
159 files changed, 2639 insertions, 651 deletions
diff --git a/README.rst b/README.rst
index 36d3d2563..c6ff99185 100644
--- a/README.rst
+++ b/README.rst
@@ -3,12 +3,13 @@
.. http://creativecommons.org/licenses/by/4.0
.. (c) OPNFV, Ericsson AB and others.
-=========
+
Yardstick
=========
+
Overview
-========
+--------
Yardstick is a framework to test non functional characteristics of an NFV
Infrastructure as perceived by an application.
@@ -19,36 +20,14 @@ the target cloud, for example OpenStack Heat.
Yardstick measures a certain service performance but can also validate the
service performance to be within a certain level of agreement.
-Yardstick is _not_ about testing OpenStack functionality (tempest) or
-benchmarking OpenStack APIs (rally).
-
-Concepts
-========
-
-Benchmark - assess the relative performance of something
+For more information on Yardstick project, please visit:
-Benchmark configuration file - describes a single test case in yaml format
+ https://wiki.opnfv.org/display/yardstick/Yardstick
+ http://artifacts.opnfv.org/yardstick/colorado/3.0/docs/userguide/index.html#document-01-introduction
-Context
-- The set of cloud resources used by a benchmark (scenario)
-– Is a simplified Heat template (context is converted into a Heat template)
-
-Data
-- Output produced by running a benchmark, written to a file in json format
-
-Runner
-- Logic that determines how the test is run
-– For example number of iterations, input value stepping, duration etc
-
-Scenario
-- Type/class of measurement for example Ping, Pktgen, (Iperf, LmBench, ...)
-
-SLA
-- Some limit to be verified (specific to scenario), for example max_latency
-– Associated action to automatically take: assert, monitor etc
Architecture
-============
+------------
Yardstick is a command line tool written in python inspired by Rally. Yardstick
is intended to run on a computer with access and credentials to a cloud. The
@@ -61,35 +40,24 @@ serially or in parallel. Each runner runs in its own subprocess executing
commands in a VM using SSH. The output of each command is written as json
records to a file.
-Install
-=======
-
-TBD
+For more information on Yardstick architecture, please read:
-Run
-===
+ http://artifacts.opnfv.org/yardstick/colorado/3.0/docs/userguide/index.html#document-03-architecture
-TBD
-Custom Image
-============
+Installation
+------------
-pktgen test requires a ubuntu server cloud image
-TBD
+Yardstick supports installation on Ubuntu 14.04 or via a Docker image.
-Development Environment
-=======================
+To learn how to install Yardstick, consult the documentation available online
+at:
-Example setup known to work for development and test:
-- Development environment: Ubuntu14.04, eclipse, virtual environment
-- Cloud: Mirantis OpenStack 6.0 deployed using Virtualbox
+ http://artifacts.opnfv.org/yardstick/colorado/3.0/docs/userguide/index.html#document-07-installation
-Install dependencies:
-$ sudo apt-get install python-virtualenv python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev
-Create a virtual environment:
-$ virtualenv ~/yardstick_venv
-$ source ~/yardstick_venv/bin/activate
-$ easy_install -U setuptools
-$ python setup.py develop
+Developers
+----------
+For information on how to contribute to Yardstick, please visit:
+ https://wiki.opnfv.org/display/yardstick/Get+started+as+a+Yardstick+developer
diff --git a/api/__init__.py b/api/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/api/__init__.py
diff --git a/api/api-prepare.sh b/api/api-prepare.sh
new file mode 100755
index 000000000..5cc65c959
--- /dev/null
+++ b/api/api-prepare.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+##############################################################################
+# 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
+##############################################################################
+
+# nginx config
+nginx_config='/etc/nginx/conf.d/yardstick.conf'
+
+if [[ ! -e "${nginx_config}" ]];then
+
+ cat << EOF > "${nginx_config}"
+server {
+ listen 5000;
+ server_name localhost;
+ index index.htm index.html;
+ location / {
+ include uwsgi_params;
+ uwsgi_pass unix:///var/run/yardstick.sock;
+ }
+}
+EOF
+echo "daemon off;" >> /etc/nginx/nginx.conf
+fi
+
+# nginx service start when boot
+supervisor_config='/etc/supervisor/conf.d/yardstick.conf'
+
+if [[ ! -e "${supervisor_config}" ]];then
+ cat << EOF > "${supervisor_config}"
+[supervisord]
+nodaemon = true
+
+[program:yardstick_nginx]
+user = root
+command = service nginx restart
+autorestart = true
+
+[program:yardstick_uwsgi]
+user = root
+directory = /home/opnfv/repos/yardstick/api
+command = uwsgi -i yardstick.ini
+autorestart = true
+EOF
+fi
+
+# create api log directory
+mkdir -p /var/log/yardstick
+
+# create yardstick.sock for communicating
+touch /var/run/yardstick.sock
diff --git a/api/base.py b/api/base.py
new file mode 100644
index 000000000..7671527d4
--- /dev/null
+++ b/api/base.py
@@ -0,0 +1,55 @@
+##############################################################################
+# 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 re
+import importlib
+import logging
+
+from flask import request
+from flask_restful import Resource
+
+from api.utils import common as common_utils
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class ApiResource(Resource):
+
+ def _post_args(self):
+ params = common_utils.translate_to_str(request.json)
+ action = params.get('action', '')
+ args = params.get('args', {})
+ logger.debug('Input args is: action: %s, args: %s', action, args)
+
+ return action, args
+
+ def _get_args(self):
+ args = common_utils.translate_to_str(request.args)
+ logger.debug('Input args is: args: %s', args)
+
+ return args
+
+ def _dispatch_post(self):
+ action, args = self._post_args()
+ return self._dispatch(args, action)
+
+ def _dispatch_get(self):
+ args = self._get_args()
+ return self._dispatch(args)
+
+ def _dispatch(self, args, action='default'):
+ module_name = re.sub(r'([A-Z][a-z]*)', r'_\1',
+ self.__class__.__name__)[1:].lower()
+
+ module_name = 'api.resources.%s' % module_name
+ resources = importlib.import_module(module_name)
+ try:
+ return getattr(resources, action)(args)
+ except NameError:
+ common_utils.error_handler('Wrong action')
diff --git a/api/conf.py b/api/conf.py
new file mode 100644
index 000000000..df44042b1
--- /dev/null
+++ b/api/conf.py
@@ -0,0 +1,27 @@
+##############################################################################
+# 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
+##############################################################################
+from pyroute2 import IPDB
+
+
+# configuration for influxdb
+with IPDB() as ip:
+ GATEWAY_IP = ip.routes['default'].gateway
+PORT = 8086
+
+TEST_ACTION = ['runTestCase']
+
+TEST_CASE_PATH = '../tests/opnfv/test_cases/'
+
+SAMPLE_PATH = '../samples/'
+
+TEST_CASE_PRE = 'opnfv_yardstick_'
+
+TEST_SUITE_PATH = '../tests/opnfv/test_suites/'
+
+OUTPUT_CONFIG_FILE_PATH = '/etc/yardstick/yardstick.conf'
diff --git a/api/database/__init__.py b/api/database/__init__.py
new file mode 100644
index 000000000..bc2708bc7
--- /dev/null
+++ b/api/database/__init__.py
@@ -0,0 +1,29 @@
+##############################################################################
+# 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 logging
+
+from sqlalchemy import create_engine
+from sqlalchemy.orm import scoped_session, sessionmaker
+from sqlalchemy.ext.declarative import declarative_base
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+engine = create_engine('sqlite:////tmp/yardstick.db', convert_unicode=True)
+db_session = scoped_session(sessionmaker(autocommit=False,
+ autoflush=False,
+ bind=engine))
+Base = declarative_base()
+Base.query = db_session.query_property()
+
+
+def init_db():
+ subclasses = [subclass.__name__ for subclass in Base.__subclasses__()]
+ logger.debug('Import models: %s', subclasses)
+ Base.metadata.create_all(bind=engine)
diff --git a/api/database/models.py b/api/database/models.py
new file mode 100644
index 000000000..25e323842
--- /dev/null
+++ b/api/database/models.py
@@ -0,0 +1,25 @@
+##############################################################################
+# 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
+##############################################################################
+from sqlalchemy import Column
+from sqlalchemy import Integer
+from sqlalchemy import String
+
+from api.database import Base
+
+
+class Tasks(Base):
+ __tablename__ = 'tasks'
+ id = Column(Integer, primary_key=True)
+ task_id = Column(String(30))
+ status = Column(Integer)
+ error = Column(String(120))
+ details = Column(String(120))
+
+ def __repr__(self):
+ return '<Task %r>' % Tasks.task_id
diff --git a/api/resources/__init__.py b/api/resources/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/api/resources/__init__.py
diff --git a/api/resources/env_action.py b/api/resources/env_action.py
new file mode 100644
index 000000000..59a1692a1
--- /dev/null
+++ b/api/resources/env_action.py
@@ -0,0 +1,259 @@
+##############################################################################
+# 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 logging
+import threading
+import subprocess
+import time
+import json
+import os
+import errno
+import ConfigParser
+
+from docker import Client
+
+from yardstick.common import constants as config
+from yardstick.common import utils as yardstick_utils
+from yardstick.common.httpClient import HttpClient
+from api import conf as api_conf
+from api.utils import influx
+from api.utils.common import result_handler
+
+logger = logging.getLogger(__name__)
+
+
+def createGrafanaContainer(args):
+ thread = threading.Thread(target=_create_grafana)
+ thread.start()
+ return result_handler('success', [])
+
+
+def _create_grafana():
+ client = Client(base_url=config.DOCKER_URL)
+
+ try:
+ if not _check_image_exist(client, '%s:%s' % (config.GRAFANA_IMAGE,
+ config.GRAFANA_TAGS)):
+ client.pull(config.GRAFANA_IMAGE, config.GRAFANA_TAGS)
+
+ _create_grafana_container(client)
+
+ time.sleep(5)
+
+ _create_data_source()
+
+ _create_dashboard()
+ except Exception as e:
+ logger.debug('Error: %s', e)
+
+
+def _create_dashboard():
+ url = 'http://admin:admin@%s:3000/api/dashboards/db' % api_conf.GATEWAY_IP
+ with open('../dashboard/ping_dashboard.json') as dashboard_json:
+ data = json.load(dashboard_json)
+ HttpClient().post(url, data)
+
+
+def _create_data_source():
+ url = 'http://admin:admin@%s:3000/api/datasources' % api_conf.GATEWAY_IP
+ data = {
+ "name": "yardstick",
+ "type": "influxdb",
+ "access": "proxy",
+ "url": "http://%s:8086" % api_conf.GATEWAY_IP,
+ "password": "root",
+ "user": "root",
+ "database": "yardstick",
+ "basicAuth": True,
+ "basicAuthUser": "admin",
+ "basicAuthPassword": "admin",
+ "isDefault": False,
+ }
+ HttpClient().post(url, data)
+
+
+def _create_grafana_container(client):
+ ports = [3000]
+ port_bindings = {k: k for k in ports}
+ host_config = client.create_host_config(port_bindings=port_bindings)
+
+ container = client.create_container(image='%s:%s' % (config.GRAFANA_IMAGE,
+ config.GRAFANA_TAGS),
+ ports=ports,
+ detach=True,
+ tty=True,
+ host_config=host_config)
+ client.start(container)
+
+
+def _check_image_exist(client, t):
+ return any(t in a['RepoTags'][0] for a in client.images() if a['RepoTags'])
+
+
+def createInfluxDBContainer(args):
+ thread = threading.Thread(target=_create_influxdb)
+ thread.start()
+ return result_handler('success', [])
+
+
+def _create_influxdb():
+ client = Client(base_url=config.DOCKER_URL)
+
+ try:
+ _change_output_to_influxdb()
+
+ if not _check_image_exist(client, '%s:%s' % (config.INFLUXDB_IMAGE,
+ config.INFLUXDB_TAG)):
+ client.pull(config.INFLUXDB_IMAGE, tag=config.INFLUXDB_TAG)
+
+ _create_influxdb_container(client)
+
+ time.sleep(5)
+
+ _config_influxdb()
+ except Exception as e:
+ logger.debug('Error: %s', e)
+
+
+def _create_influxdb_container(client):
+
+ ports = [8083, 8086]
+ port_bindings = {k: k for k in ports}
+ host_config = client.create_host_config(port_bindings=port_bindings)
+
+ container = client.create_container(image='%s:%s' % (config.INFLUXDB_IMAGE,
+ config.INFLUXDB_TAG),
+ ports=ports,
+ detach=True,
+ tty=True,
+ host_config=host_config)
+ client.start(container)
+
+
+def _config_influxdb():
+ try:
+ client = influx.get_data_db_client()
+ client.create_user(config.USER, config.PASSWORD, config.DATABASE)
+ client.create_database(config.DATABASE)
+ logger.info('Success to config influxDB')
+ except Exception as e:
+ logger.debug('Failed to config influxDB: %s', e)
+
+
+def _change_output_to_influxdb():
+ yardstick_utils.makedirs(config.YARDSTICK_CONFIG_DIR)
+
+ parser = ConfigParser.ConfigParser()
+ parser.read(config.YARDSTICK_CONFIG_SAMPLE_FILE)
+
+ parser.set('DEFAULT', 'dispatcher', 'influxdb')
+ parser.set('dispatcher_influxdb', 'target',
+ 'http://%s:8086' % api_conf.GATEWAY_IP)
+
+ with open(config.YARDSTICK_CONFIG_FILE, 'w') as f:
+ parser.write(f)
+
+
+def prepareYardstickEnv(args):
+ thread = threading.Thread(target=_prepare_env_daemon)
+ thread.start()
+ return result_handler('success', [])
+
+
+def _prepare_env_daemon():
+
+ installer_ip = os.environ.get('INSTALLER_IP', 'undefined')
+ installer_type = os.environ.get('INSTALLER_TYPE', 'undefined')
+
+ _check_variables(installer_ip, installer_type)
+
+ _create_directories()
+
+ rc_file = config.OPENSTACK_RC_FILE
+
+ _get_remote_rc_file(rc_file, installer_ip, installer_type)
+
+ _source_file(rc_file)
+
+ _append_external_network(rc_file)
+
+ # update the external_network
+ _source_file(rc_file)
+
+ _clean_images()
+
+ _load_images()
+
+
+def _check_variables(installer_ip, installer_type):
+
+ if installer_ip == 'undefined':
+ raise SystemExit('Missing INSTALLER_IP')
+
+ if installer_type == 'undefined':
+ raise SystemExit('Missing INSTALLER_TYPE')
+ elif installer_type not in config.INSTALLERS:
+ raise SystemExit('INSTALLER_TYPE is not correct')
+
+
+def _create_directories():
+ yardstick_utils.makedirs(config.YARDSTICK_CONFIG_DIR)
+
+
+def _source_file(rc_file):
+ yardstick_utils.source_env(rc_file)
+
+
+def _get_remote_rc_file(rc_file, installer_ip, installer_type):
+
+ os_fetch_script = os.path.join(config.RELENG_DIR, config.OS_FETCH_SCRIPT)
+
+ try:
+ cmd = [os_fetch_script, '-d', rc_file, '-i', installer_type,
+ '-a', installer_ip]
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ p.communicate()[0]
+
+ if p.returncode != 0:
+ logger.debug('Failed to fetch credentials from installer')
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+
+
+def _append_external_network(rc_file):
+ neutron_client = yardstick_utils.get_neutron_client()
+ networks = neutron_client.list_networks()['networks']
+ try:
+ ext_network = next(n['name'] for n in networks if n['router:external'])
+ except StopIteration:
+ logger.warning("Can't find external network")
+ else:
+ cmd = 'export EXTERNAL_NETWORK=%s' % ext_network
+ try:
+ with open(rc_file, 'a') as f:
+ f.write(cmd + '\n')
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+
+
+def _clean_images():
+ cmd = [config.CLEAN_IMAGES_SCRIPT]
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ cwd=config.YARDSTICK_REPOS_DIR)
+ output = p.communicate()[0]
+ logger.debug('The result is: %s', output)
+
+
+def _load_images():
+ cmd = [config.LOAD_IMAGES_SCRIPT]
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ cwd=config.YARDSTICK_REPOS_DIR)
+ output = p.communicate()[0]
+ logger.debug('The result is: %s', output)
diff --git a/api/resources/release_action.py b/api/resources/release_action.py
new file mode 100644
index 000000000..fda0ffd32
--- /dev/null
+++ b/api/resources/release_action.py
@@ -0,0 +1,38 @@
+##############################################################################
+# 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 uuid
+import os
+import logging
+
+from api import conf
+from api.utils import common as common_utils
+
+logger = logging.getLogger(__name__)
+
+
+def runTestCase(args):
+ try:
+ opts = args.get('opts', {})
+ testcase = args['testcase']
+ except KeyError:
+ return common_utils.error_handler('Lack of testcase argument')
+
+ testcase = os.path.join(conf.TEST_CASE_PATH,
+ conf.TEST_CASE_PRE + testcase + '.yaml')
+
+ task_id = str(uuid.uuid4())
+
+ command_list = ['task', 'start']
+ command_list = common_utils.get_command_list(command_list, opts, testcase)
+ logger.debug('The command_list is: %s', command_list)
+
+ logger.debug('Start to execute command list')
+ common_utils.exec_command_task(command_list, task_id)
+
+ return common_utils.result_handler('success', task_id)
diff --git a/api/resources/results.py b/api/resources/results.py
new file mode 100644
index 000000000..3de09fdc9
--- /dev/null
+++ b/api/resources/results.py
@@ -0,0 +1,67 @@
+##############################################################################
+# 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 logging
+import uuid
+import re
+
+from api.utils import influx as influx_utils
+from api.utils import common as common_utils
+from api import conf
+
+logger = logging.getLogger(__name__)
+
+
+def default(args):
+ return getResult(args)
+
+
+def getResult(args):
+ try:
+ measurement = args['measurement']
+ task_id = args['task_id']
+
+ if re.search("[^a-zA-Z0-9_-]", measurement):
+ raise ValueError('invalid measurement parameter')
+
+ uuid.UUID(task_id)
+ except KeyError:
+ message = 'measurement and task_id must be provided'
+ return common_utils.error_handler(message)
+
+ query_template = "select * from %s where task_id='%s'"
+ query_sql = query_template % ('tasklist', task_id)
+ data = common_utils.translate_to_str(influx_utils.query(query_sql))
+
+ def _unfinished():
+ return common_utils.result_handler(0, [])
+
+ def _finished():
+ query_sql = query_template % (conf.TEST_CASE_PRE + measurement,
+ task_id)
+ data = common_utils.translate_to_str(influx_utils.query(query_sql))
+ if not data:
+ query_sql = query_template % (measurement, task_id)
+ data = common_utils.translate_to_str(influx_utils.query(query_sql))
+
+ return common_utils.result_handler(1, data)
+
+ def _error():
+ return common_utils.result_handler(2, data[0]['error'])
+
+ try:
+ status = data[0]['status']
+
+ switcher = {
+ 0: _unfinished,
+ 1: _finished,
+ 2: _error
+ }
+ return switcher.get(status, lambda: 'nothing')()
+ except IndexError:
+ return common_utils.error_handler('no such task')
diff --git a/api/resources/samples_action.py b/api/resources/samples_action.py
new file mode 100644
index 000000000..545447aec
--- /dev/null
+++ b/api/resources/samples_action.py
@@ -0,0 +1,37 @@
+##############################################################################
+# 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 uuid
+import os
+import logging
+
+from api import conf
+from api.utils import common as common_utils
+
+logger = logging.getLogger(__name__)
+
+
+def runTestCase(args):
+ try:
+ opts = args.get('opts', {})
+ testcase = args['testcase']
+ except KeyError:
+ return common_utils.error_handler('Lack of testcase argument')
+
+ testcase = os.path.join(conf.SAMPLE_PATH, testcase + '.yaml')
+
+ task_id = str(uuid.uuid4())
+
+ command_list = ['task', 'start']
+ command_list = common_utils.get_command_list(command_list, opts, testcase)
+ logger.debug('The command_list is: %s', command_list)
+
+ logger.debug('Start to execute command list')
+ common_utils.exec_command_task(command_list, task_id)
+
+ return common_utils.result_handler('success', task_id)
diff --git a/api/server.py b/api/server.py
new file mode 100644
index 000000000..fac821b00
--- /dev/null
+++ b/api/server.py
@@ -0,0 +1,43 @@
+##############################################################################
+# 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 logging
+
+from flask import Flask
+from flask_restful import Api
+from flasgger import Swagger
+
+from api.database import init_db
+from api.database import db_session
+from api.urls import urlpatterns
+from yardstick import _init_logging
+
+logger = logging.getLogger(__name__)
+
+app = Flask(__name__)
+
+init_db()
+
+Swagger(app)
+
+api = Api(app)
+
+
+@app.teardown_request
+def shutdown_session(exception=None):
+ db_session.remove()
+
+
+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/swagger/__init__.py b/api/swagger/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/api/swagger/__init__.py
diff --git a/api/swagger/docs/results.yaml b/api/swagger/docs/results.yaml
new file mode 100644
index 000000000..7bdab3eb6
--- /dev/null
+++ b/api/swagger/docs/results.yaml
@@ -0,0 +1,41 @@
+Query task result data
+
+This api offer the interface to get the result data via task_id
+We will return a result json dict
+---
+tags:
+ - Results
+parameters:
+ -
+ in: query
+ name: action
+ type: string
+ default: getResult
+ required: true
+ -
+ in: query
+ name: measurement
+ type: string
+ description: test case name
+ required: true
+ -
+ in: query
+ name: task_id
+ type: string
+ description: the task_id you get before
+ required: true
+responses:
+ 200:
+ description: a result json dict
+ schema:
+ id: ResultModel
+ properties:
+ status:
+ type: string
+ description: the status of the certain task
+ default: success
+ result:
+ schema:
+ type: array
+ items:
+ type: object
diff --git a/api/swagger/docs/testcases.yaml b/api/swagger/docs/testcases.yaml
new file mode 100644
index 000000000..7bfe5e647
--- /dev/null
+++ b/api/swagger/docs/testcases.yaml
@@ -0,0 +1,50 @@
+TestCases Actions
+
+This API may offer many actions, including runTestCase
+
+action: runTestCase
+This api offer the interface to run a test case in yardstick
+we will return a task_id for querying
+you can use the returned task_id to get the result data
+---
+tags:
+ - Release Action
+parameters:
+ - in: body
+ name: body
+ description: this is the input json dict
+ schema:
+ id: TestCaseActionModel
+ required:
+ - action
+ - args
+ properties:
+ action:
+ type: string
+ description: this is action for testcases
+ default: runTestCase
+ args:
+ schema:
+ id: TestCaseActionArgsModel
+ required:
+ - testcase
+ properties:
+ testcase:
+ type: string
+ description: this is the test case name
+ default: tc002
+ opts:
+ schema:
+ id: TestCaseActionArgsOptsModel
+responses:
+ 200:
+ description: A result json dict
+ schema:
+ id: result
+ properties:
+ status:
+ type: string
+ default: success
+ result:
+ type: string
+ description: task_id of this task
diff --git a/api/swagger/models.py b/api/swagger/models.py
new file mode 100644
index 000000000..7c65fbbf5
--- /dev/null
+++ b/api/swagger/models.py
@@ -0,0 +1,51 @@
+##############################################################################
+# 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
+##############################################################################
+from flask_restful import fields
+from flask_restful_swagger import swagger
+
+
+# for testcases/action runTestCase action
+@swagger.model
+class TestCaseActionArgsOptsTaskArgModel:
+ resource_fields = {
+ }
+
+
+@swagger.model
+class TestCaseActionArgsOptsModel:
+ resource_fields = {
+ 'task-args': TestCaseActionArgsOptsTaskArgModel,
+ 'keep-deploy': fields.String,
+ 'suite': fields.String
+ }
+
+
+@swagger.model
+class TestCaseActionArgsModel:
+ resource_fields = {
+ 'testcase': fields.String,
+ 'opts': TestCaseActionArgsOptsModel
+ }
+
+
+@swagger.model
+class TestCaseActionModel:
+ resource_fields = {
+ 'action': fields.String,
+ 'args': TestCaseActionArgsModel
+ }
+
+
+# for results
+@swagger.model
+class ResultModel:
+ resource_fields = {
+ 'status': fields.String,
+ 'result': fields.List
+ }
diff --git a/api/urls.py b/api/urls.py
new file mode 100644
index 000000000..0fffd12db
--- /dev/null
+++ b/api/urls.py
@@ -0,0 +1,18 @@
+##############################################################################
+# 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
+##############################################################################
+from api import views
+from api.utils.common import Url
+
+
+urlpatterns = [
+ Url('/yardstick/testcases/release/action', views.ReleaseAction, 'release'),
+ Url('/yardstick/testcases/samples/action', views.SamplesAction, 'samples'),
+ Url('/yardstick/results', views.Results, 'results'),
+ Url('/yardstick/env/action', views.EnvAction, 'env')
+]
diff --git a/api/utils/__init__.py b/api/utils/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/api/utils/__init__.py
diff --git a/api/utils/common.py b/api/utils/common.py
new file mode 100644
index 000000000..e3e64a72b
--- /dev/null
+++ b/api/utils/common.py
@@ -0,0 +1,71 @@
+##############################################################################
+# 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 collections
+import logging
+
+from flask import jsonify
+
+from api.utils.daemonthread import DaemonThread
+from yardstick.cmd.cli import YardstickCLI
+
+logger = logging.getLogger(__name__)
+
+
+def translate_to_str(object):
+ if isinstance(object, collections.Mapping):
+ return {str(k): translate_to_str(v) for k, v in object.items()}
+ elif isinstance(object, list):
+ return [translate_to_str(ele) for ele in object]
+ elif isinstance(object, unicode):
+ return str(object)
+ return object
+
+
+def get_command_list(command_list, opts, args):
+
+ command_list.append(args)
+
+ command_list.extend(('--{}'.format(k) for k in opts if 'task-args' != k))
+
+ task_args = opts.get('task-args', '')
+ if task_args:
+ command_list.extend(['--task-args', str(task_args)])
+
+ return command_list
+
+
+def exec_command_task(command_list, task_id): # pragma: no cover
+ daemonthread = DaemonThread(YardstickCLI().api, (command_list, task_id))
+ daemonthread.start()
+
+
+def error_handler(message):
+ logger.debug(message)
+ result = {
+ 'status': 'error',
+ 'message': message
+ }
+ return jsonify(result)
+
+
+def result_handler(status, data):
+ result = {
+ 'status': status,
+ 'result': data
+ }
+ return jsonify(result)
+
+
+class Url(object):
+
+ def __init__(self, url, resource, endpoint):
+ super(Url, self).__init__()
+ self.url = url
+ self.resource = resource
+ self.endpoint = endpoint
diff --git a/api/utils/daemonthread.py b/api/utils/daemonthread.py
new file mode 100644
index 000000000..47c0b9108
--- /dev/null
+++ b/api/utils/daemonthread.py
@@ -0,0 +1,44 @@
+##############################################################################
+# 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 threading
+import os
+import datetime
+import errno
+
+from api import conf
+from api.utils.influx import write_data_tasklist
+
+
+class DaemonThread(threading.Thread):
+
+ def __init__(self, method, args):
+ super(DaemonThread, self).__init__(target=method, args=args)
+ self.method = method
+ self.command_list = args[0]
+ self.task_id = args[1]
+
+ def run(self):
+ timestamp = datetime.datetime.now()
+
+ try:
+ write_data_tasklist(self.task_id, timestamp, 0)
+ self.method(self.command_list, self.task_id)
+ write_data_tasklist(self.task_id, timestamp, 1)
+ except Exception as e:
+ write_data_tasklist(self.task_id, timestamp, 2, error=str(e))
+ finally:
+ _handle_testsuite_file(self.task_id)
+
+
+def _handle_testsuite_file(task_id):
+ try:
+ os.remove(os.path.join(conf.TEST_SUITE_PATH, task_id + '.yaml'))
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
diff --git a/api/utils/influx.py b/api/utils/influx.py
new file mode 100644
index 000000000..9366ed3e9
--- /dev/null
+++ b/api/utils/influx.py
@@ -0,0 +1,73 @@
+##############################################################################
+# 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 logging
+from urlparse import urlsplit
+
+from influxdb import InfluxDBClient
+import ConfigParser
+
+from api import conf
+
+logger = logging.getLogger(__name__)
+
+
+def get_data_db_client():
+ parser = ConfigParser.ConfigParser()
+ try:
+ parser.read(conf.OUTPUT_CONFIG_FILE_PATH)
+ dispatcher = parser.get('DEFAULT', 'dispatcher')
+
+ if 'influxdb' != dispatcher:
+ raise RuntimeError
+
+ ip = _get_ip(parser.get('dispatcher_influxdb', 'target'))
+ username = parser.get('dispatcher_influxdb', 'username')
+ password = parser.get('dispatcher_influxdb', 'password')
+ db_name = parser.get('dispatcher_influxdb', 'db_name')
+ return InfluxDBClient(ip, conf.PORT, username, password, db_name)
+ except ConfigParser.NoOptionError:
+ logger.error('can not find the key')
+ raise
+
+
+def _get_ip(url):
+ return urlsplit(url).hostname
+
+
+def _write_data(measurement, field, timestamp, tags):
+ point = {
+ 'measurement': measurement,
+ 'fields': field,
+ 'time': timestamp,
+ 'tags': tags
+ }
+
+ try:
+ client = get_data_db_client()
+
+ logger.debug('Start to write data: %s', point)
+ client.write_points([point])
+ except RuntimeError:
+ logger.debug('dispatcher is not influxdb')
+
+
+def write_data_tasklist(task_id, timestamp, status, error=''):
+ field = {'status': status, 'error': error}
+ tags = {'task_id': task_id}
+ _write_data('tasklist', field, timestamp, tags)
+
+
+def query(query_sql):
+ try:
+ client = get_data_db_client()
+ logger.debug('Start to query: %s', query_sql)
+ return list(client.query(query_sql).get_points())
+ except RuntimeError:
+ logger.error('dispatcher is not influxdb')
+ raise
diff --git a/api/views.py b/api/views.py
new file mode 100644
index 000000000..ee13b47a9
--- /dev/null
+++ b/api/views.py
@@ -0,0 +1,49 @@
+##############################################################################
+# 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 logging
+import os
+
+from flasgger.utils import swag_from
+
+from api.base import ApiResource
+from api.swagger import models
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+TestCaseActionModel = models.TestCaseActionModel
+TestCaseActionArgsModel = models.TestCaseActionArgsModel
+TestCaseActionArgsOptsModel = models.TestCaseActionArgsOptsModel
+TestCaseActionArgsOptsTaskArgModel = models.TestCaseActionArgsOptsTaskArgModel
+
+
+class ReleaseAction(ApiResource):
+ @swag_from(os.getcwd() + '/swagger/docs/testcases.yaml')
+ def post(self):
+ return self._dispatch_post()
+
+
+class SamplesAction(ApiResource):
+ def post(self):
+ return self._dispatch_post()
+
+
+ResultModel = models.ResultModel
+
+
+class Results(ApiResource):
+ @swag_from(os.getcwd() + '/swagger/docs/results.yaml')
+ def get(self):
+ return self._dispatch_get()
+
+
+class EnvAction(ApiResource):
+ def post(self):
+ return self._dispatch_post()
diff --git a/api/yardstick.ini b/api/yardstick.ini
new file mode 100644
index 000000000..2ba881fc1
--- /dev/null
+++ b/api/yardstick.ini
@@ -0,0 +1,16 @@
+[uwsgi]
+master = true
+debug = true
+chdir = /home/opnfv/repos/yardstick/api
+module = server
+plugins = python
+processes = 10
+threads = 5
+async = true
+max-requests = 5000
+chmod-socket = 666
+callable = app
+enable-threads = true
+close-on-exec = 1
+daemonize= /var/log/yardstick/uwsgi.log
+socket = /var/run/yardstick.sock
diff --git a/dashboard/ping_dashboard.json b/dashboard/ping_dashboard.json
new file mode 100644
index 000000000..538fe065b
--- /dev/null
+++ b/dashboard/ping_dashboard.json
@@ -0,0 +1 @@
+{"meta":{"type":"db","canSave":true,"canEdit":true,"canStar":true,"slug":null,"expires":"0001-01-01T00:00:00Z","created":"2016-10-09T00:45:46Z","updated":"2016-10-09T03:12:01Z","updatedBy":"admin","createdBy":"admin","version":7},"dashboard":{"id":null,"title":"opnfv_yardstick_tc002","tags":[],"style":"dark","timezone":"browser","editable":true,"hideControls":false,"sharedCrosshair":false,"rows":[{"title":"New row","height":"25px","editable":true,"collapse":false,"panels":[{"title":"","error":false,"span":12,"editable":true,"type":"text","isNew":true,"id":2,"mode":"html","content":"<div class=\"text-center\" style=\"padding: 10px 0 5px 0\">\n<style>\nh1 {\n\ttext-shadow: -1px -1px 1px #fff, 1px 1px 1px #31A7D3;\n\tcolor: #31A7D3;\n\topacity: 0.8;\n\tfont: 50px '31A7D3';\n}\n</style>\n<body>\n<h1>Ping Dashboard</h1>\n</body>","links":[],"height":"25"}]},{"collapse":false,"editable":true,"height":"250px","panels":[{"aliasColors":{},"bars":false,"datasource":"yardstick","editable":true,"error":false,"fill":1,"grid":{"threshold1":1,"threshold1Color":"rgba(216, 200, 27, 0.27)","threshold2":0.5,"threshold2Color":"rgba(234, 112, 112, 0.22)","thresholdLine":false},"id":1,"isNew":true,"legend":{"alignAsTable":false,"avg":false,"current":false,"max":true,"min":true,"rightSide":false,"show":false,"total":false,"values":true},"lines":true,"linewidth":2,"links":[],"nullPointMode":"connected","percentage":false,"pointradius":5,"points":true,"renderer":"flot","seriesOverrides":[],"span":12,"stack":false,"steppedLine":false,"targets":[{"dsType":"influxdb","groupBy":[{"params":["$interval"],"type":"time"},{"params":["null"],"type":"fill"}],"measurement":"opnfv_yardstick_tc002","policy":"default","refId":"A","resultFormat":"time_series","select":[[{"params":["rtt.ares"],"type":"field"},{"params":[],"type":"mean"}]],"tags":[]}],"timeFrom":null,"timeShift":null,"title":"","tooltip":{"msResolution":true,"shared":true,"sort":0,"value_type":"cumulative"},"type":"graph","xaxis":{"show":true},"yaxes":[{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":true},{"format":"short","label":null,"logBase":1,"max":null,"min":null,"show":true}]}],"title":"Row"}],"time":{"from":"now-5m","to":"now"},"timepicker":{"refresh_intervals":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"templating":{"list":[]},"annotations":{"list":[]},"refresh":"10s","schemaVersion":12,"version":2,"links":[],"gnetId":null}}
diff --git a/docker/Dockerfile b/docker/Dockerfile
index fba6e2067..23afef74e 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
@@ -43,8 +45,12 @@ RUN apt-get update && apt-get install -y \
python-dev \
libxml2-dev \
libxslt1-dev \
+ nginx \
+ uwsgi \
+ uwsgi-plugin-python \
+ supervisor \
python-setuptools && \
- easy_install -U setuptools
+ easy_install -U setuptools==30.0.0
RUN apt-get -y autoremove && \
apt-get clean
@@ -52,15 +58,20 @@ RUN apt-get -y autoremove && \
RUN mkdir -p ${REPOS_DIR}
RUN git config --global http.sslVerify false
-RUN git clone https://gerrit.opnfv.org/gerrit/yardstick ${YARDSTICK_REPO_DIR}
-RUN git clone https://gerrit.opnfv.org/gerrit/releng ${RELENG_REPO_DIR}
+RUN git clone --depth 1 -b $BRANCH https://gerrit.opnfv.org/gerrit/yardstick ${YARDSTICK_REPO_DIR}
+RUN git clone --depth 1 https://gerrit.opnfv.org/gerrit/releng ${RELENG_REPO_DIR}
# install yardstick + dependencies
RUN cd ${YARDSTICK_REPO_DIR} && easy_install -U pip
RUN cd ${YARDSTICK_REPO_DIR} && pip install -r requirements.txt
RUN cd ${YARDSTICK_REPO_DIR} && pip install .
+RUN ${YARDSTICK_REPO_DIR}/api/api-prepare.sh
+
+EXPOSE 5000
+
ADD http://download.cirros-cloud.net/0.3.3/cirros-0.3.3-x86_64-disk.img /home/opnfv/images/
ADD http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img /home/opnfv/images/
COPY ./exec_tests.sh /usr/local/bin/
+CMD ["/usr/bin/supervisord"]
diff --git a/docs/release/release-notes.rst b/docs/release/release-notes.rst
index 72f263c2d..8df0776df 100644
--- a/docs/release/release-notes.rst
+++ b/docs/release/release-notes.rst
@@ -38,7 +38,10 @@ Version History
| *Date* | *Version* | *Comment* |
| | | |
+----------------+--------------------+---------------------------------+
-| Oct 27nd, 2016 | 2.0 | Yardstick for Colorado release |
+| Dec 5th, 2016 | 3.0 | Yardstick for Colorado release |
+| | | |
++----------------+--------------------+---------------------------------+
+| Oct 27th, 2016 | 2.0 | Yardstick for Colorado release |
| | | |
+----------------+--------------------+---------------------------------+
| Aug 22nd, 2016 | 1.0 | Yardstick for Colorado release |
@@ -132,19 +135,19 @@ Release Data
| **Project** | Yardstick |
| | |
+--------------------------------------+--------------------------------------+
-| **Repo/tag** | yardstick/colorado.2.0 |
+| **Repo/tag** | yardstick/colorado.3.0 |
| | |
+--------------------------------------+--------------------------------------+
-| **Yardstick Docker image tag** | colorado.2.0 |
+| **Yardstick Docker image tag** | colorado.3.0 |
| | |
+--------------------------------------+--------------------------------------+
| **Release designation** | Colorado |
| | |
+--------------------------------------+--------------------------------------+
-| **Release date** | October 27 2016 |
+| **Release date** | December 5th, 2016 |
| | |
+--------------------------------------+--------------------------------------+
-| **Purpose of the delivery** | OPNFV Colorado release 2.0 |
+| **Purpose of the delivery** | OPNFV Colorado release 3.0 |
| | |
+--------------------------------------+--------------------------------------+
@@ -163,22 +166,22 @@ Documents
Software Deliverables
---------------------
-**Yardstick framework source code <colorado.2.0>**
+**Yardstick framework source code <colorado.3.0>**
+--------------------------------------+--------------------------------------+
| **Project** | Yardstick |
| | |
+--------------------------------------+--------------------------------------+
-| **Repo/tag** | yardstick/colorado.2.0 |
+| **Repo/tag** | yardstick/colorado.3.0 |
| | |
+--------------------------------------+--------------------------------------+
-| **Yardstick Docker image tag** | colorado.2.0 |
+| **Yardstick Docker image tag** | colorado.3.0 |
| | |
+--------------------------------------+--------------------------------------+
| **Release designation** | Colorado |
| | |
+--------------------------------------+--------------------------------------+
-| **Release date** | October 27th, 2016 |
+| **Release date** | December 5th, 2016 |
| | |
+--------------------------------------+--------------------------------------+
| **Purpose of the delivery** | OPNFV Colorado release |
@@ -502,7 +505,7 @@ Feature additions
Scenario Matrix
===============
-For Colorado 2.0, Yardstick was tested on the following scenarios:
+For Colorado 3.0, Yardstick was tested on the following scenarios:
+-------------------------+---------+---------+---------+---------+
| Scenario | Apex | Compass | Fuel | Joid |
@@ -585,6 +588,21 @@ Known Issues/Faults
Corrected Faults
----------------
+Colorado.3.0:
+
++----------------------------+------------------------------------------------+
+| **JIRA REFERENCE** | **SLOGAN** |
+| | |
++----------------------------+------------------------------------------------+
+| JIRA: YARDSTICK-239 | Define process for working with Yardstick |
+| | Grafana dashboard. |
+| | |
++----------------------------+------------------------------------------------+
+| JIRA: YARDSTICK-373 | Add os-odl_l2-fdio-ha scenario support. |
+| | |
++----------------------------+------------------------------------------------+
+
+
Colorado.2.0:
+----------------------------+------------------------------------------------+
@@ -621,7 +639,7 @@ Colorado.2.0:
+----------------------------+------------------------------------------------+
-Colorado 2.0 known restrictions/issues
+Colorado 3.0 known restrictions/issues
==================================
+-----------+-----------+----------------------------------------------+
| Installer | Scenario | Issue |
@@ -656,6 +674,8 @@ Useful links
- Yardstick IRC chanel: #opnfv-yardstick
+.. _`YARDSTICK-239` : https://jira.opnfv.org/browse/YARDSTICK-239
+
.. _`YARDSTICK-325` : https://jira.opnfv.org/browse/YARDSTICK-325
.. _`YARDSTICK-358` : https://jira.opnfv.org/browse/YARDSTICK-358
@@ -669,3 +689,5 @@ Useful links
.. _`YARDSTICK-371` : https://jira.opnfv.org/browse/YARDSTICK-371
.. _`YARDSTICK-372` : https://jira.opnfv.org/browse/YARDSTICK-372
+
+.. _`YARDSTICK-373` : https://jira.opnfv.org/browse/YARDSTICK-373
diff --git a/docs/userguide/07-installation.rst b/docs/userguide/07-installation.rst
index 09d36bf25..9c2082a27 100644
--- a/docs/userguide/07-installation.rst
+++ b/docs/userguide/07-installation.rst
@@ -211,9 +211,9 @@ Example command:
::
glance --os-image-api-version 1 image-create \
- --name yardstick-trusty-server --is-public true \
+ --name yardstick-image --is-public true \
--disk-format qcow2 --container-format bare \
- --file /tmp/workspace/yardstick/yardstick-trusty-server.img
+ --file /tmp/workspace/yardstick/yardstick-image.img
Some Yardstick test cases use a Cirros image, you can find one at
http://download.cirros-cloud.net/0.3.3/cirros-0.3.3-x86_64-disk.img
diff --git a/etc/yardstick/yardstick.conf.sample b/etc/yardstick/yardstick.conf.sample
index f4eff05d3..70cf71ade 100644
--- a/etc/yardstick/yardstick.conf.sample
+++ b/etc/yardstick/yardstick.conf.sample
@@ -8,22 +8,21 @@
##############################################################################
[DEFAULT]
-# verbose = True
-# debug = True
-# dispatcher = http
+debug = False
+dispatcher = http
[dispatcher_http]
-# timeout = 5
-# target = http://127.0.0.1:8000/results
+timeout = 5
+target = http://127.0.0.1:8000/results
[dispatcher_file]
-# file_path = /tmp/yardstick.out
-# max_bytes = 0
-# backup_count = 0
+file_path = /tmp/yardstick.out
+max_bytes = 0
+backup_count = 0
[dispatcher_influxdb]
-# timeout = 5
-# target = http://127.0.0.1:8086
-# db_name = yardstick
-# username = root
-# password = root
+timeout = 5
+target = http://127.0.0.1:8086
+db_name = yardstick
+username = root
+password = root
diff --git a/install.sh b/install.sh
index 80fc1e523..e9b6035d9 100755
--- a/install.sh
+++ b/install.sh
@@ -13,6 +13,10 @@ apt-get update && apt-get install -y \
python-dev \
libxml2-dev \
libxslt1-dev \
+ nginx \
+ uwsgi \
+ uwsgi-plugin-python \
+ supervisor \
python-setuptools && \
easy_install -U setuptools
diff --git a/requirements.txt b/requirements.txt
index 4d1a16993..9c037ed79 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -38,7 +38,7 @@ netaddr==0.7.18
netifaces==0.10.4
nose==1.3.7
openstacksdk==0.8.1
-os-client-config==1.16.0
+os-client-config==1.22.0
oslo.config==3.9.0
oslo.i18n==3.4.0
oslo.serialization==2.4.0
@@ -52,19 +52,19 @@ pycrypto==2.6.1
pyflakes==1.0.0
pyparsing==2.1.0
pyrsistent==0.11.12
-python-cinderclient==1.6.0
-python-glanceclient==2.0.0
-python-heatclient==1.0.0
-python-keystoneclient==2.3.1
+python-cinderclient==1.9.0
+python-glanceclient==2.5.0
+python-heatclient==1.5.0
+python-keystoneclient==3.6.0
python-mimeparse==1.5.1
-python-neutronclient==4.1.1
-python-novaclient==3.3.0
-python-openstackclient==2.2.0
+python-neutronclient==6.0.0
+python-novaclient==6.0.0
+python-openstackclient==3.3.0
python-subunit==1.2.0
python-swiftclient==3.0.0
pytz==2015.7
PyYAML==3.11
-requests==2.9.1
+requests==2.10.0
requestsexceptions==1.1.3
scp==0.10.2
simplejson==3.8.2
@@ -77,3 +77,11 @@ unicodecsv==0.14.1
unittest2==1.1.0
warlock==1.2.0
wrapt==1.10.6
+flask==0.11.1
+flask-restful==0.3.5
+influxdb==3.0.0
+pyroute2==0.4.10
+docker-py==1.10.6
+flasgger==0.5.13
+flask-restful-swagger==0.19
+SQLAlchemy==1.1.4
diff --git a/samples/background-task.yaml b/samples/background-task.yaml
index a844c2d7f..11cfdd567 100644
--- a/samples/background-task.yaml
+++ b/samples/background-task.yaml
@@ -39,7 +39,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/cachestat.yaml b/samples/cachestat.yaml
index 5786efa38..d736793e3 100644
--- a/samples/cachestat.yaml
+++ b/samples/cachestat.yaml
@@ -18,7 +18,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/cyclictest.yaml b/samples/cyclictest.yaml
index cb85decb1..eaf74893e 100644
--- a/samples/cyclictest.yaml
+++ b/samples/cyclictest.yaml
@@ -33,7 +33,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
servers:
diff --git a/samples/fio-template.yaml b/samples/fio-template.yaml
index ba710d95f..00c35ce23 100644
--- a/samples/fio-template.yaml
+++ b/samples/fio-template.yaml
@@ -28,7 +28,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
servers:
diff --git a/samples/fio.yaml b/samples/fio.yaml
index e1f5e6d2d..5ccbc1954 100644
--- a/samples/fio.yaml
+++ b/samples/fio.yaml
@@ -37,7 +37,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
servers:
diff --git a/samples/iperf3-jitter.yaml b/samples/iperf3-jitter.yaml
index c211571d0..366a57152 100644
--- a/samples/iperf3-jitter.yaml
+++ b/samples/iperf3-jitter.yaml
@@ -23,7 +23,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/iperf3.yaml b/samples/iperf3.yaml
index 72f260942..6741c767e 100644
--- a/samples/iperf3.yaml
+++ b/samples/iperf3.yaml
@@ -21,7 +21,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/lmbench.yaml b/samples/lmbench.yaml
index 311770c42..595a393b7 100644
--- a/samples/lmbench.yaml
+++ b/samples/lmbench.yaml
@@ -48,7 +48,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/lmbench_cache.yaml b/samples/lmbench_cache.yaml
index 7a22cf15f..bf5086b3c 100644
--- a/samples/lmbench_cache.yaml
+++ b/samples/lmbench_cache.yaml
@@ -26,7 +26,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/memload.yaml b/samples/memload.yaml
index 87d727707..5e988986a 100644
--- a/samples/memload.yaml
+++ b/samples/memload.yaml
@@ -20,7 +20,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/netperf.yaml b/samples/netperf.yaml
index 4d7f7a798..0dd56348b 100755
--- a/samples/netperf.yaml
+++ b/samples/netperf.yaml
@@ -46,7 +46,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/netperf_bottlenecks.yaml b/samples/netperf_bottlenecks.yaml
new file mode 100644
index 000000000..4b6348109
--- /dev/null
+++ b/samples/netperf_bottlenecks.yaml
@@ -0,0 +1,43 @@
+---
+# measure network latency and throughput using netperf
+# This test case is suite for bottlenecks project.
+# This test case is from TC073
+# we have did some parameters support
+
+schema: "yardstick:task:0.1"
+
+{% set host = host or "node1.LF" %}
+{% set target = target or "node2.LF" %}
+{% set pod_info = pod_info or "etc/yardstick/nodes/compass_sclab_virtual/pod.yaml" %}
+{% set tx_msg_size = tx_msg_size or "65536" %}
+{% set rx_msg_size = rx_msg_size or "87380" %}
+{% set test_time = test_time or "20" %}
+{% set out_opt = out_opt or "THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY,LOCAL_CPU_UTIL,REMOTE_CPU_UTIL,LOCAL_TRANSPORT_RETRANS" %}
+
+scenarios:
+-
+ type: NetperfNode
+ options:
+ testname: 'TCP_STREAM'
+ send_msg_size: {{tx_msg_size}}
+ recv_msg_size: {{rx_msg_size}}
+ duration: {{test_time}}
+ output_opt: {{out_opt}}
+
+ host: {{host}}
+ target: {{target}}
+
+ runner:
+ type: Iteration
+ iterations: 1
+ interval: 1
+ run_step: 'setup,run'
+
+ sla:
+ mean_latency: 100
+ action: monitor
+
+context:
+ type: Node
+ name: LF
+ file: {{pod_info}}
diff --git a/samples/netutilization.yaml b/samples/netutilization.yaml
index 598a5af15..794342d29 100644
--- a/samples/netutilization.yaml
+++ b/samples/netutilization.yaml
@@ -19,7 +19,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/perf.yaml b/samples/perf.yaml
index 541f846e7..b8979b511 100644
--- a/samples/perf.yaml
+++ b/samples/perf.yaml
@@ -30,7 +30,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/ping-ext-ip.yaml b/samples/ping-ext-ip.yaml
index d36c29544..3ce71e8a7 100644
--- a/samples/ping-ext-ip.yaml
+++ b/samples/ping-ext-ip.yaml
@@ -24,7 +24,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
servers:
hermes:
diff --git a/samples/ping-ext-stimuli.yaml b/samples/ping-ext-stimuli.yaml
index 451f0105f..d7efe063f 100644
--- a/samples/ping-ext-stimuli.yaml
+++ b/samples/ping-ext-stimuli.yaml
@@ -37,7 +37,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
servers:
goofy:
diff --git a/samples/ping-heat-context.yaml b/samples/ping-heat-context.yaml
index 5a8d09fbe..913912e50 100644
--- a/samples/ping-heat-context.yaml
+++ b/samples/ping-heat-context.yaml
@@ -25,7 +25,7 @@ context:
type: Heat
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
placement_groups:
diff --git a/samples/ping-hot.yaml b/samples/ping-hot.yaml
index b4b8f5228..1619a561f 100644
--- a/samples/ping-hot.yaml
+++ b/samples/ping-hot.yaml
@@ -33,7 +33,7 @@ context:
heat_template: /tmp/heat-templates/hot/servers_in_new_neutron_net.yaml
heat_parameters:
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
key_name: yardstick
public_net: "660fc7c3-7a56-4faf-91e5-3c9ebdda0104"
private_net_name: "test"
diff --git a/samples/ping-iteration.yaml b/samples/ping-iteration.yaml
index a5e90941b..d399b399a 100755
--- a/samples/ping-iteration.yaml
+++ b/samples/ping-iteration.yaml
@@ -24,7 +24,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
placement_groups:
diff --git a/samples/ping-multiple-context.yaml b/samples/ping-multiple-context.yaml
index 1c27e1bf1..71b7994ff 100644
--- a/samples/ping-multiple-context.yaml
+++ b/samples/ping-multiple-context.yaml
@@ -24,7 +24,7 @@ contexts:
-
name: demo1
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
placement_groups:
pgrp1:
@@ -39,7 +39,7 @@ contexts:
-
name: demo2
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
placement_groups:
pgrp1:
diff --git a/samples/ping-multiple-vm.yaml b/samples/ping-multiple-vm.yaml
index 4055af14b..e8ebf495e 100644
--- a/samples/ping-multiple-vm.yaml
+++ b/samples/ping-multiple-vm.yaml
@@ -28,7 +28,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
servers:
diff --git a/samples/ping-option-list.yaml b/samples/ping-option-list.yaml
index 30d133eb8..1c31677ac 100644
--- a/samples/ping-option-list.yaml
+++ b/samples/ping-option-list.yaml
@@ -22,7 +22,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
placement_groups:
diff --git a/samples/ping-parallel.yaml b/samples/ping-parallel.yaml
index 00d261383..5761543b4 100644
--- a/samples/ping-parallel.yaml
+++ b/samples/ping-parallel.yaml
@@ -36,7 +36,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
placement_groups:
diff --git a/samples/ping-serial.yaml b/samples/ping-serial.yaml
index 9c492e481..59653db34 100644
--- a/samples/ping-serial.yaml
+++ b/samples/ping-serial.yaml
@@ -35,7 +35,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
servers:
diff --git a/samples/ping-template.yaml b/samples/ping-template.yaml
index cfc79206a..825dde285 100644
--- a/samples/ping-template.yaml
+++ b/samples/ping-template.yaml
@@ -29,7 +29,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
placement_groups:
diff --git a/samples/ping.yaml b/samples/ping.yaml
index 845d10dcc..5e922ea56 100644
--- a/samples/ping.yaml
+++ b/samples/ping.yaml
@@ -24,7 +24,7 @@ scenarios:
context:
name: demo
image: cirros-0.3.3
- flavor: m1.tiny
+ flavor: yardstick-flavor
user: cirros
placement_groups:
diff --git a/samples/pktgen.yaml b/samples/pktgen.yaml
index ddafb27bd..6acb8ab92 100644
--- a/samples/pktgen.yaml
+++ b/samples/pktgen.yaml
@@ -38,7 +38,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/ramspeed.yaml b/samples/ramspeed.yaml
index 7e1b1aa8c..e754fc9fa 100644
--- a/samples/ramspeed.yaml
+++ b/samples/ramspeed.yaml
@@ -25,7 +25,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/samples/unixbench.yaml b/samples/unixbench.yaml
index 825fd767f..b7ab88190 100644
--- a/samples/unixbench.yaml
+++ b/samples/unixbench.yaml
@@ -21,7 +21,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/setup.py b/setup.py
index 6a89d6368..0100b4635 100755
--- a/setup.py
+++ b/setup.py
@@ -25,10 +25,12 @@ setup(
'resources/scripts/remove/*.bash'
],
'etc': [
- 'yardstick/nodes/*/*.yaml'
+ 'yardstick/nodes/*/*.yaml',
+ 'yardstick/*.sample'
],
'tests': [
- 'opnfv/*/*.yaml'
+ 'opnfv/*/*.yaml',
+ 'ci/*.sh'
]
},
url="https://www.opnfv.org",
diff --git a/tests/ci/clean_images.sh b/tests/ci/clean_images.sh
index 05f68a7ed..fa4a54df6 100755
--- a/tests/ci/clean_images.sh
+++ b/tests/ci/clean_images.sh
@@ -15,15 +15,22 @@ cleanup()
echo
echo "========== Cleanup =========="
- if ! glance image-list; then
+ if ! openstack image list; then
return
fi
- for image in $(glance image-list | grep -e cirros-0.3.3 -e yardstick-trusty-server -e Ubuntu-14.04 \
+ for image in $(openstack image list | grep -e cirros-0.3.3 -e yardstick-image -e Ubuntu-14.04 \
-e yardstick-vivid-kernel | awk '{print $2}'); do
echo "Deleting image $image..."
- glance image-delete $image || true
+ openstack image delete $image || true
done
- nova flavor-delete yardstick-flavor &> /dev/null || true
+ openstack flavor delete yardstick-flavor &> /dev/null || true
}
+
+main()
+{
+ cleanup
+}
+
+main
diff --git a/tests/ci/load_images.sh b/tests/ci/load_images.sh
index 49b972777..e1d717749 100755
--- a/tests/ci/load_images.sh
+++ b/tests/ci/load_images.sh
@@ -12,6 +12,18 @@
set -e
+YARD_IMG_ARCH=amd64
+export YARD_IMG_ARCH
+
+if ! grep -q "Defaults env_keep += \"YARD_IMG_ARCH\"" "/etc/sudoers"; then
+ sudo echo "Defaults env_keep += \"YARD_IMG_ARCH YARDSTICK_REPO_DIR\"" >> /etc/sudoers
+fi
+
+ARCH_SCRIPT="test -f /etc/fuel_openstack_arch && grep -q arm64 /etc/fuel_openstack_arch"
+if [ "$INSTALLER_TYPE" == "fuel" ]; then
+ sshpass -p r00tme ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -l root $INSTALLER_IP "${ARCH_SCRIPT}" && YARD_IMG_ARCH=arm64
+fi
+
UCA_HOST="cloud-images.ubuntu.com"
if [ $YARD_IMG_ARCH = "arm64" ]; then
export VIVID_IMG_URL="http://${UCA_HOST}/vivid/current/vivid-server-cloudimg-arm64.tar.gz"
@@ -63,11 +75,12 @@ load_yardstick_image()
if [ ! -f $VIVID_KERNEL ]; then
tar zxf $VIVID_IMAGE $(basename $VIVID_KERNEL)
fi
- create_vivid_kernel=$(glance --os-image-api-version 1 image-create \
- --name yardstick-vivid-kernel \
- --is-public true --disk-format qcow2 \
+ create_vivid_kernel=$(openstack image create \
+ --public \
+ --disk-format qcow2 \
--container-format bare \
- --file $VIVID_KERNEL)
+ --file $VIVID_KERNEL \
+ yardstick-vivid-kernel)
GLANCE_KERNEL_ID=$(echo "$create_vivid_kernel" | grep " id " | awk '{print $(NF-1)}')
if [ -z "$GLANCE_KERNEL_ID" ]; then
@@ -89,19 +102,21 @@ load_yardstick_image()
fi
if [[ "$DEPLOY_SCENARIO" == *"-lxd-"* ]]; then
- output=$(eval glance --os-image-api-version 1 image-create \
- --name yardstick-trusty-server \
- --is-public true --disk-format root-tar \
+ output=$(eval openstack image create \
+ --public \
+ --disk-format root-tar \
--container-format bare \
$EXTRA_PARAMS \
- --file $RAW_IMAGE)
+ --file $RAW_IMAGE \
+ yardstick-image)
else
- output=$(eval glance --os-image-api-version 1 image-create \
- --name yardstick-trusty-server \
- --is-public true --disk-format qcow2 \
+ output=$(eval openstack image create \
+ --public \
+ --disk-format qcow2 \
--container-format bare \
$EXTRA_PARAMS \
- --file $QCOW_IMAGE)
+ --file $QCOW_IMAGE \
+ yardstick-image)
fi
echo "$output"
@@ -135,12 +150,12 @@ load_cirros_image()
EXTRA_PARAMS=$EXTRA_PARAMS" --property hw_mem_page_size=large"
fi
- output=$(glance image-create \
- --name cirros-0.3.3 \
+ output=$(openstack image create \
--disk-format qcow2 \
--container-format bare \
$EXTRA_PARAMS \
- --file $image_file)
+ --file $image_file \
+ cirros-0.3.3)
echo "$output"
CIRROS_IMAGE_ID=$(echo "$output" | grep " id " | awk '{print $(NF-1)}')
@@ -165,12 +180,12 @@ load_ubuntu_image()
EXTRA_PARAMS=$EXTRA_PARAMS" --property hw_mem_page_size=large"
fi
- output=$(glance image-create \
- --name Ubuntu-14.04 \
+ output=$(openstack image create \
--disk-format qcow2 \
--container-format bare \
$EXTRA_PARAMS \
- --file $ubuntu_image_file)
+ --file $ubuntu_image_file \
+ Ubuntu-14.04)
echo "$output"
UBUNTU_IMAGE_ID=$(echo "$output" | grep " id " | awk '{print $(NF-1)}')
@@ -185,26 +200,26 @@ load_ubuntu_image()
create_nova_flavor()
{
- if ! nova flavor-list | grep -q yardstick-flavor; then
+ if ! openstack flavor list | grep -q yardstick-flavor; then
echo
echo "========== Create nova flavor =========="
# Create the nova flavor used by some sample test cases
- nova flavor-create yardstick-flavor 100 512 3 1
+ openstack flavor create --id 100 --ram 512 --disk 3 --vcpus 1 yardstick-flavor
# DPDK-enabled OVS requires guest memory to be backed by large pages
if [[ "$DEPLOY_SCENARIO" == *"-ovs-"* ]]; then
- nova flavor-key yardstick-flavor set hw:mem_page_size=large
+ openstack flavor set --property hw:mem_page_size=large yardstick-flavor
fi
# VPP requires guest memory to be backed by large pages
if [[ "$DEPLOY_SCENARIO" == *"-fdio-"* ]]; then
- nova flavor-key yardstick-flavor set hw:mem_page_size=large
+ openstack flavor set --property hw:mem_page_size=large yardstick-flavor
fi
fi
}
main()
{
- QCOW_IMAGE="/tmp/workspace/yardstick/yardstick-trusty-server.img"
- RAW_IMAGE="/tmp/workspace/yardstick/yardstick-trusty-server.tar.gz"
+ QCOW_IMAGE="/tmp/workspace/yardstick/yardstick-image.img"
+ RAW_IMAGE="/tmp/workspace/yardstick/yardstick-image.tar.gz"
build_yardstick_image
load_yardstick_image
diff --git a/tests/ci/prepare_env.sh b/tests/ci/prepare_env.sh
index 130969fa1..be59b7f37 100755
--- a/tests/ci/prepare_env.sh
+++ b/tests/ci/prepare_env.sh
@@ -74,13 +74,6 @@ verify_connectivity() {
error "Can not talk to $ip."
}
-YARD_IMG_ARCH=amd64
-export YARD_IMG_ARCH
-
-if ! grep -q "Defaults env_keep += \"YARD_IMG_ARCH\"" "/etc/sudoers"; then
- sudo echo "Defaults env_keep += \"YARD_IMG_ARCH YARDSTICK_REPO_DIR\"" >> /etc/sudoers
-fi
-
ssh_options="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
if [ "$INSTALLER_TYPE" == "fuel" ]; then
@@ -90,9 +83,6 @@ if [ "$INSTALLER_TYPE" == "fuel" ]; then
sshpass -p r00tme scp 2>/dev/null $ssh_options \
root@${INSTALLER_IP}:~/.ssh/id_rsa /root/.ssh/id_rsa &> /dev/null
- ARCH_SCRIPT="test -f /etc/fuel_openstack_arch && grep -q arm64 /etc/fuel_openstack_arch"
- sshpass -p r00tme ssh $ssh_options -l root $INSTALLER_IP "${ARCH_SCRIPT}" && YARD_IMG_ARCH=arm64
-
sshpass -p r00tme ssh 2>/dev/null $ssh_options \
root@${INSTALLER_IP} fuel node>fuel_node
diff --git a/tests/ci/prepare_storperf_admin-rc.sh b/tests/ci/prepare_storperf_admin-rc.sh
index 0401719ff..b3dc2e58e 100755
--- a/tests/ci/prepare_storperf_admin-rc.sh
+++ b/tests/ci/prepare_storperf_admin-rc.sh
@@ -9,14 +9,15 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
+# Prepare storperf_admin-rc for StorPerf.
+
AUTH_URL=${OS_AUTH_URL}
USERNAME=${OS_USERNAME:-admin}
PASSWORD=${OS_PASSWORD:-console}
TENANT_NAME=${OS_TENANT_NAME:-admin}
VOLUME_API_VERSION=${OS_VOLUME_API_VERSION:-2}
PROJECT_NAME=${OS_PROJECT_NAME:-$TENANT_NAME}
-TENANT_ID=`keystone tenant-get admin|grep 'id'|awk -F '|' '{print $3}'|sed -e 's/^[[:space:]]*//'`
-
+TENANT_ID=`openstack project show admin|grep '\bid\b' |awk -F '|' '{print $3}'|sed -e 's/^[[:space:]]*//'`
rm -f ~/storperf_admin-rc
touch ~/storperf_admin-rc
diff --git a/tests/ci/requirements.txt b/tests/ci/requirements.txt
deleted file mode 100644
index 4d1a16993..000000000
--- a/tests/ci/requirements.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-##############################################################################
-# Copyright (c) 2015 Ericsson AB 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
-##############################################################################
-
-appdirs==1.4.0
-Babel==2.2.0
-backport-ipaddress==0.1
-cliff==2.0.0
-cmd2==0.6.8
-coverage==4.1b2
-debtcollector==1.3.0
-ecdsa==0.13
-extras==0.0.3
-fixtures==1.4.0
-flake8==2.5.4
-funcsigs==0.4
-functools32==3.2.3.post2
-futures==3.0.5
-iso8601==0.1.11
-Jinja2==2.8
-jsonpatch==1.13
-jsonpointer==1.10
-jsonschema==2.5.1
-keystoneauth1==2.3.0
-linecache2==1.0.0
-lxml==3.5.0
-MarkupSafe==0.23
-mccabe==0.4.0
-mock==1.3.0
-monotonic==1.0
-msgpack-python==0.4.7
-netaddr==0.7.18
-netifaces==0.10.4
-nose==1.3.7
-openstacksdk==0.8.1
-os-client-config==1.16.0
-oslo.config==3.9.0
-oslo.i18n==3.4.0
-oslo.serialization==2.4.0
-oslo.utils==3.7.0
-paramiko==1.16.0
-pbr==1.8.1
-pep8==1.7.0
-positional==1.0.1
-prettytable==0.7.2
-pycrypto==2.6.1
-pyflakes==1.0.0
-pyparsing==2.1.0
-pyrsistent==0.11.12
-python-cinderclient==1.6.0
-python-glanceclient==2.0.0
-python-heatclient==1.0.0
-python-keystoneclient==2.3.1
-python-mimeparse==1.5.1
-python-neutronclient==4.1.1
-python-novaclient==3.3.0
-python-openstackclient==2.2.0
-python-subunit==1.2.0
-python-swiftclient==3.0.0
-pytz==2015.7
-PyYAML==3.11
-requests==2.9.1
-requestsexceptions==1.1.3
-scp==0.10.2
-simplejson==3.8.2
-six==1.10.0
-stevedore==1.12.0
-testrepository==0.0.20
-testtools==2.0.0
-traceback2==1.4.0
-unicodecsv==0.14.1
-unittest2==1.1.0
-warlock==1.2.0
-wrapt==1.10.6
diff --git a/tests/ci/scp_storperf_admin-rc.sh b/tests/ci/scp_storperf_admin-rc.sh
index af2885b01..7c3896d88 100644
--- a/tests/ci/scp_storperf_admin-rc.sh
+++ b/tests/ci/scp_storperf_admin-rc.sh
@@ -1,5 +1,16 @@
#!/bin/bash
+##############################################################################
+# 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
+##############################################################################
+
+# Copy storperf_admin-rc to deployment location.
+
ssh_options="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
sshpass -p root scp 2>/dev/null $ssh_options ~/storperf_admin-rc \
root@192.168.200.1:/root/ &> /dev/null
diff --git a/tests/ci/yardstick-verify b/tests/ci/yardstick-verify
index 2b7ec9d34..f9d98a4da 100755
--- a/tests/ci/yardstick-verify
+++ b/tests/ci/yardstick-verify
@@ -160,9 +160,9 @@ run_test()
mkdir -p /etc/yardstick
- cat << EOF >> /etc/yardstick/yardstick.conf
+ cat << EOF > /etc/yardstick/yardstick.conf
[DEFAULT]
-debug = True
+debug = False
dispatcher = ${DISPATCHER_TYPE}
[dispatcher_file]
@@ -301,8 +301,8 @@ main()
# check OpenStack services
echo "Checking OpenStack services:"
- for cmd in "glance image-list" "nova list" "heat stack-list"; do
- echo " checking ${cmd/%\ */} ..."
+ for cmd in "openstack image list" "openstack server list" "openstack stack list"; do
+ echo " checking ${cmd} ..."
if ! $cmd >/dev/null; then
echo "error: command \"$cmd\" failed"
exit 1
@@ -311,7 +311,7 @@ main()
echo
echo "Checking for External network:"
- for net in $(neutron net-list --router:external True -c name -f value); do
+ for net in $(openstack network list --external -c Name -f value); do
echo " external network: $net"
done
@@ -320,8 +320,6 @@ main()
source $YARDSTICK_REPO_DIR/tests/ci/clean_images.sh
- cleanup
-
trap "error_exit" EXIT SIGTERM
source $YARDSTICK_REPO_DIR/tests/ci/load_images.sh
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml
index 899ee963c..aa2980f69 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml
@@ -31,7 +31,7 @@ scenarios:
context:
name: yardstick
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml
index 6e50157fc..f5a2778e8 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml
@@ -35,8 +35,8 @@ scenarios:
context:
name: yardstick-TC005
- image: yardstick-trusty-server
- flavor: m1.small
+ image: yardstick-image
+ flavor: yardstick-flavor
user: ubuntu
servers:
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml
index 8b21c5bf1..7221518ab 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml
@@ -16,7 +16,7 @@ scenarios:
vlan_net_2_name: apexlake_outbound_network
vlan_subnet_2_name: apexlake_outbound_subnet
vnic_type: direct
- vtc_flavor: m1.large
+ vtc_flavor: yardstick-flavor
runner:
type: Iteration
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml
index 107c28d1d..6f99ea6f2 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml
@@ -19,7 +19,7 @@ scenarios:
vlan_net_2_name: apexlake_outbound_network
vlan_subnet_2_name: apexlake_outbound_subnet
vnic_type: direct
- vtc_flavor: m1.large
+ vtc_flavor: yardstick-flavor
num_of_neighbours: 2
amount_of_ram: 1G
number_of_cores: 2
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml
index 1cec80ff6..a2f5f3adc 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml
@@ -37,7 +37,7 @@ scenarios:
context:
name: yardstick-TC008
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml
index 82a55d751..f9fa1b778 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml
@@ -32,7 +32,7 @@ scenarios:
context:
name: yardstick-TC009
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml
index aeb18543e..6c7f96799 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml
@@ -25,8 +25,8 @@ scenarios:
context:
name: yardstick-TC010
- image: yardstick-trusty-server
- flavor: m1.small
+ image: yardstick-image
+ flavor: yardstick-flavor
user: ubuntu
servers:
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml
index 5d21e2814..4cd3119bb 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml
@@ -23,7 +23,7 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml
index 3bdb8cb9a..ba246ff11 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml
@@ -26,8 +26,8 @@ scenarios:
context:
name: demo
- image: yardstick-trusty-server
- flavor: m1.small
+ image: yardstick-image
+ flavor: yardstick-flavor
user: ubuntu
servers:
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml
index 648657f22..1ac0f2961 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml
@@ -19,7 +19,7 @@ scenarios:
context:
name: yardstick-TC014
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
@@ -29,4 +29,4 @@ context:
networks:
test:
- cidr: '10.0.1.0/24' \ No newline at end of file
+ cidr: '10.0.1.0/24'
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml
index 7e5756001..cbdaf3970 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml
@@ -15,7 +15,7 @@ scenarios:
vlan_net_2_name: apexlake_outbound_network
vlan_subnet_2_name: apexlake_outbound_subnet
vnic_type: direct
- vtc_flavor: m1.large
+ vtc_flavor: yardstick-flavor
runner:
type: Iteration
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml
index 769d75618..17249785a 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml
@@ -15,7 +15,7 @@ scenarios:
vlan_net_2_name: apexlake_outbound_network
vlan_subnet_2_name: apexlake_outbound_subnet
vnic_type: direct
- vtc_flavor: m1.large
+ vtc_flavor: yardstick-flavor
num_of_neighbours: 2
amount_of_ram: 1G
number_of_cores: 2
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml
index 5e2177a6e..cd42098d2 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml
@@ -64,7 +64,7 @@ scenarios:
context:
name: yardstick-TC037
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml
index 128f94045..c2e5b4028 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml
@@ -64,7 +64,7 @@ scenarios:
context:
name: yardstick-TC038
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml
index 637e160c6..dcc34d80d 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml
@@ -25,7 +25,7 @@ scenarios:
context:
name: yardstick-TC069
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml
index 28b28b9ab..931587b5b 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml
@@ -66,7 +66,7 @@ scenarios:
context:
name: yardstick-TC070
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml
index 644010916..6f006eeaf 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml
@@ -64,7 +64,7 @@ scenarios:
context:
name: yardstick-TC071
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml
index f3e6d4c40..e1fa33173 100644
--- a/tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml
+++ b/tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml
@@ -66,7 +66,7 @@ scenarios:
context:
name: yardstick-TC072
- image: yardstick-trusty-server
+ image: yardstick-image
flavor: yardstick-flavor
user: ubuntu
diff --git a/tests/opnfv/test_suites/opnfv_components.yaml b/tests/opnfv/test_suites/opnfv_components.yaml
new file mode 100644
index 000000000..ff4923e03
--- /dev/null
+++ b/tests/opnfv/test_suites/opnfv_components.yaml
@@ -0,0 +1,16 @@
+---
+# Yardstick components task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "opnfv_yardstick-components"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc074.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"public_network": "ext-net",
+ "StorPerf_ip": "192.168.200.1"}'
diff --git a/tests/opnfv/test_suites/opnfv_features.yaml b/tests/opnfv/test_suites/opnfv_features.yaml
new file mode 100644
index 000000000..3621f1367
--- /dev/null
+++ b/tests/opnfv/test_suites/opnfv_features.yaml
@@ -0,0 +1,52 @@
+---
+# Yardstick features task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "opnfv_yardstick-features"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc027.yaml
+ constraint:
+ installer: compass,fuel
+ pod: huawei-pod1,lf-pod2
+ task_args:
+ huawei-pod1: '{"pod_info": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml"}'
+ lf-pod2: '{"pod_info": "etc/yardstick/nodes/fuel_baremetal/pod.yaml", "openrc":"/root/openrc", "external_network":"admin_floating_net"}'
+-
+ file_name: opnfv_yardstick_tc045.yaml
+ constraint:
+ installer: fuel
+-
+ file_name: opnfv_yardstick_tc046.yaml
+ constraint:
+ installer: fuel
+-
+ file_name: opnfv_yardstick_tc047.yaml
+ constraint:
+ installer: fuel
+-
+ file_name: opnfv_yardstick_tc048.yaml
+ constraint:
+ installer: fuel
+-
+ file_name: opnfv_yardstick_tc049.yaml
+ constraint:
+ installer: fuel
+-
+ file_name: opnfv_yardstick_tc050.yaml
+ constraint:
+ installer: fuel
+-
+ file_name: opnfv_yardstick_tc051.yaml
+ constraint:
+ installer: fuel
+-
+ file_name: opnfv_yardstick_tc052.yaml
+ constraint:
+ installer: fuel
+-
+ file_name: opnfv_yardstick_tc053.yaml
+ constraint:
+ installer: fuel
diff --git a/tests/opnfv/test_suites/opnfv_performance.yaml b/tests/opnfv/test_suites/opnfv_performance.yaml
new file mode 100644
index 000000000..71b1e2ef9
--- /dev/null
+++ b/tests/opnfv/test_suites/opnfv_performance.yaml
@@ -0,0 +1,62 @@
+---
+# Yardstick performance task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "opnfv_yardstick-performance"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc002.yaml
+-
+ file_name: opnfv_yardstick_tc005.yaml
+-
+ file_name: opnfv_yardstick_tc010.yaml
+-
+ file_name: opnfv_yardstick_tc011.yaml
+-
+ file_name: opnfv_yardstick_tc012.yaml
+-
+ file_name: opnfv_yardstick_tc014.yaml
+-
+ file_name: opnfv_yardstick_tc037.yaml
+-
+ file_name: opnfv_yardstick_tc043.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"pod_info": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml",
+ "host": "node4.LF","target": "node5.LF"}'
+-
+ file_name: opnfv_yardstick_tc055.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"pod_info": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml",
+ "host": "node5.yardstick-TC055"}'
+-
+ file_name: opnfv_yardstick_tc063.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"pod_info": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml",
+ "host": "node5.yardstick-TC063"}'
+-
+ file_name: opnfv_yardstick_tc069.yaml
+-
+ file_name: opnfv_yardstick_tc070.yaml
+-
+ file_name: opnfv_yardstick_tc071.yaml
+-
+ file_name: opnfv_yardstick_tc072.yaml
+-
+ file_name: opnfv_yardstick_tc075.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"pod_info": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml",
+ "host": "node1.LF"}'
diff --git a/tests/opnfv/test_suites/opnfv_smoke.yaml b/tests/opnfv/test_suites/opnfv_smoke.yaml
new file mode 100644
index 000000000..f773bec87
--- /dev/null
+++ b/tests/opnfv/test_suites/opnfv_smoke.yaml
@@ -0,0 +1,14 @@
+---
+# Yardstick smoke task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "opnfv_yardstick-smoke"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc002.yaml
+-
+ file_name: opnfv_yardstick_tc005.yaml
+-
+ file_name: opnfv_yardstick_tc012.yaml
diff --git a/tests/unit/api/utils/test_common.py b/tests/unit/api/utils/test_common.py
new file mode 100644
index 000000000..5d177409e
--- /dev/null
+++ b/tests/unit/api/utils/test_common.py
@@ -0,0 +1,65 @@
+##############################################################################
+# 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
+
+from api.utils import common
+
+
+class TranslateToStrTestCase(unittest.TestCase):
+
+ def test_translate_to_str_unicode(self):
+ input_str = u'hello'
+ output_str = common.translate_to_str(input_str)
+
+ result = 'hello'
+ self.assertEqual(result, output_str)
+
+ def test_translate_to_str_dict_list_unicode(self):
+ input_str = {
+ u'hello': {u'hello': [u'world']}
+ }
+ output_str = common.translate_to_str(input_str)
+
+ result = {
+ 'hello': {'hello': ['world']}
+ }
+ self.assertEqual(result, output_str)
+
+
+class GetCommandListTestCase(unittest.TestCase):
+
+ def test_get_command_list_no_opts(self):
+ command_list = ['a']
+ opts = {}
+ args = 'b'
+ output_list = common.get_command_list(command_list, opts, args)
+
+ result_list = ['a', 'b']
+ self.assertEqual(result_list, output_list)
+
+ def test_get_command_list_with_opts_args(self):
+ command_list = ['a']
+ opts = {
+ 'b': 'c',
+ 'task-args': 'd'
+ }
+ args = 'e'
+
+ output_list = common.get_command_list(command_list, opts, args)
+
+ result_list = ['a', 'e', '--b', '--task-args', 'd']
+ self.assertEqual(result_list, output_list)
+
+
+def main():
+ unittest.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/unit/api/utils/test_influx.py b/tests/unit/api/utils/test_influx.py
new file mode 100644
index 000000000..0852da2dd
--- /dev/null
+++ b/tests/unit/api/utils/test_influx.py
@@ -0,0 +1,82 @@
+##############################################################################
+# 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 uuid
+import datetime
+
+from api.utils import influx
+
+
+class GetDataDbClientTestCase(unittest.TestCase):
+
+ @mock.patch('api.utils.influx.ConfigParser')
+ def test_get_data_db_client_dispatcher_not_influxdb(self, mock_parser):
+ mock_parser.ConfigParser().get.return_value = 'file'
+ try:
+ influx.get_data_db_client()
+ except Exception as e:
+ self.assertIsInstance(e, RuntimeError)
+
+
+class GetIpTestCase(unittest.TestCase):
+
+ def test_get_url(self):
+ url = 'http://localhost:8086/hello'
+ output = influx._get_ip(url)
+
+ result = 'localhost'
+ self.assertEqual(result, output)
+
+
+class WriteDataTestCase(unittest.TestCase):
+
+ @mock.patch('api.utils.influx.get_data_db_client')
+ def test_write_data(self, mock_get_client):
+ measurement = 'tasklist'
+ field = {'status': 1}
+ timestamp = datetime.datetime.now()
+ tags = {'task_id': str(uuid.uuid4())}
+
+ influx._write_data(measurement, field, timestamp, tags)
+ mock_get_client.assert_called_with()
+
+
+class WriteDataTasklistTestCase(unittest.TestCase):
+
+ @mock.patch('api.utils.influx._write_data')
+ def test_write_data_tasklist(self, mock_write_data):
+ task_id = str(uuid.uuid4())
+ timestamp = datetime.datetime.now()
+ status = 1
+ influx.write_data_tasklist(task_id, timestamp, status)
+
+ field = {'status': status, 'error': ''}
+ tags = {'task_id': task_id}
+ mock_write_data.assert_called_with('tasklist', field, timestamp, tags)
+
+
+class QueryTestCase(unittest.TestCase):
+
+ @mock.patch('api.utils.influx.ConfigParser')
+ def test_query_dispatcher_not_influxdb(self, mock_parser):
+ mock_parser.ConfigParser().get.return_value = 'file'
+ try:
+ sql = 'select * form tasklist'
+ influx.query(sql)
+ except Exception as e:
+ self.assertIsInstance(e, RuntimeError)
+
+
+def main():
+ unittest.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/unit/benchmark/scenarios/networking/test_vsperf.py b/tests/unit/benchmark/scenarios/networking/test_vsperf.py
index cb5c09ab3..25d52212b 100644
--- a/tests/unit/benchmark/scenarios/networking/test_vsperf.py
+++ b/tests/unit/benchmark/scenarios/networking/test_vsperf.py
@@ -39,17 +39,17 @@ class VsperfTestCase(unittest.TestCase):
}
self.args = {
'options': {
- 'testname': 'rfc2544_p2p_continuous',
+ 'testname': 'p2p_rfc2544_continuous',
'traffic_type': 'continuous',
- 'pkt_sizes': '64',
+ 'frame_size': '64',
'bidirectional': 'True',
'iload': 100,
- 'duration': 29,
'trafficgen_port1': 'eth1',
'trafficgen_port2': 'eth3',
'external_bridge': 'br-ex',
- 'conf-file': 'vsperf-yardstick.conf',
- 'setup-script': 'setup_yardstick.sh',
+ 'conf_file': 'vsperf-yardstick.conf',
+ 'setup_script': 'setup_yardstick.sh',
+ 'test_params': 'TRAFFICGEN_DURATION=30;',
},
'sla': {
'metrics': 'throughput_rx_fps',
diff --git a/tests/unit/benchmark/scenarios/storage/test_storperf.py b/tests/unit/benchmark/scenarios/storage/test_storperf.py
index d87ed733c..8fc97d2ed 100644
--- a/tests/unit/benchmark/scenarios/storage/test_storperf.py
+++ b/tests/unit/benchmark/scenarios/storage/test_storperf.py
@@ -43,7 +43,7 @@ def mocked_requests_job_get(*args, **kwargs):
self.content = json_data
self.status_code = status_code
- return MockResponseJobGet('{"_ssd_preconditioning.queue-depth.8.block-size.16384.duration": 6}', 200)
+ return MockResponseJobGet('{"status": "completed", "_ssd_preconditioning.queue-depth.8.block-size.16384.duration": 6}', 200)
def mocked_requests_job_post(*args, **kwargs):
@@ -152,7 +152,7 @@ class StorPerfTestCase(unittest.TestCase):
s = storperf.StorPerf(args, self.ctx)
s.setup_done = True
- sample_output = '{"_ssd_preconditioning.queue-depth.8.block-size.16384.duration": 6}'
+ sample_output = '{"status": "completed", "_ssd_preconditioning.queue-depth.8.block-size.16384.duration": 6}'
expected_result = json.loads(sample_output)
diff --git a/tests/unit/cmd/commands/test_env.py b/tests/unit/cmd/commands/test_env.py
new file mode 100644
index 000000000..af1ab8030
--- /dev/null
+++ b/tests/unit/cmd/commands/test_env.py
@@ -0,0 +1,29 @@
+##############################################################################
+# 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 yardstick.cmd.commands.env import EnvCommand
+
+
+class EnvCommandTestCase(unittest.TestCase):
+
+ @mock.patch('yardstick.cmd.commands.env.HttpClient')
+ def test_do_influxdb(self, mock_http_client):
+ env = EnvCommand()
+ env.do_influxdb({})
+ self.assertTrue(mock_http_client().post.called)
+
+
+def main():
+ unittest.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/unit/common/test_httpClient.py b/tests/unit/common/test_httpClient.py
new file mode 100644
index 000000000..b39dc2332
--- /dev/null
+++ b/tests/unit/common/test_httpClient.py
@@ -0,0 +1,33 @@
+##############################################################################
+# 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 yardstick.common import httpClient
+
+
+class HttpClientTestCase(unittest.TestCase):
+
+ @mock.patch('yardstick.common.httpClient.requests')
+ def test_post(self, mock_requests):
+ url = 'http://localhost:5000/hello'
+ data = {'hello': 'world'}
+ headers = {'Content-Type': 'application/json'}
+ httpClient.HttpClient().post(url, data)
+ mock_requests.post.assert_called_with(url, data=json.dumps(data),
+ headers=headers)
+
+
+def main():
+ unittest.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/unit/common/test_openstack_utils.py b/tests/unit/common/test_openstack_utils.py
new file mode 100644
index 000000000..ef619aace
--- /dev/null
+++ b/tests/unit/common/test_openstack_utils.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+##############################################################################
+# 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
+##############################################################################
+
+# Unittest for yardstick.common.openstack_utils
+
+import unittest
+import mock
+
+from yardstick.common import openstack_utils
+
+
+class GetCredentialsTestCase(unittest.TestCase):
+
+ @mock.patch('yardstick.common.openstack_utils.os')
+ def test_get_credentials(self, mock_os):
+ mock_os.getenv.return_value = ('2')
+ openstack_utils.get_credentials()
+
+
+class GetHeatApiVersionTestCase(unittest.TestCase):
+
+ @mock.patch('yardstick.common.openstack_utils.os')
+ def test_get_heat_api_version(self, mock_os):
+ API = 'HEAT_API_VERSION'
+ openstack_utils.get_heat_api_version()
+ mock_os.getenv.assert_called_with(API)
+
+ @mock.patch('yardstick.common.openstack_utils.os')
+ def test_get_heat_api_version(self, mock_os):
+ mock_os.getenv.return_value = ('2')
+ expected_result = '2'
+ api_version = openstack_utils.get_heat_api_version()
+ self.assertEqual(api_version, expected_result)
diff --git a/tests/unit/test_ssh.py b/tests/unit/test_ssh.py
index a27052462..045ac0f1b 100644
--- a/tests/unit/test_ssh.py
+++ b/tests/unit/test_ssh.py
@@ -17,7 +17,10 @@
# rally/tests/unit/common/test_sshutils.py
import os
+import socket
import unittest
+from cStringIO import StringIO
+
import mock
from yardstick import ssh
@@ -162,10 +165,10 @@ class SSHTestCase(unittest.TestCase):
def test_send_command(self, mock_paramiko):
paramiko_sshclient = self.test_client._get_client()
with mock.patch.object(paramiko_sshclient, "exec_command") \
- as mock_paramiko_exec_command:
+ as mock_paramiko_exec_command:
self.test_client.send_command('cmd')
mock_paramiko_exec_command.assert_called_once_with('cmd',
- get_pty=True)
+ get_pty=True)
class SSHRunTestCase(unittest.TestCase):
@@ -275,6 +278,23 @@ class SSHRunTestCase(unittest.TestCase):
self.assertEqual(send_calls, self.fake_session.send.mock_calls)
@mock.patch("yardstick.ssh.select")
+ def test_run_stdin_keep_open(self, mock_select):
+ """Test run method with stdin.
+
+ Third send call was called with "e2" because only 3 bytes was sent
+ by second call. So remainig 2 bytes of "line2" was sent by third call.
+ """
+ mock_select.select.return_value = ([], [], [])
+ self.fake_session.exit_status_ready.side_effect = [0, 0, 0, True]
+ self.fake_session.send_ready.return_value = True
+ self.fake_session.send.side_effect = len
+ fake_stdin = StringIO("line1\nline2\n")
+ self.test_client.run("cmd", stdin=fake_stdin, keep_stdin_open=True)
+ call = mock.call
+ send_calls = [call("line1\nline2\n")]
+ self.assertEqual(send_calls, self.fake_session.send.mock_calls)
+
+ @mock.patch("yardstick.ssh.select")
def test_run_select_error(self, mock_select):
self.fake_session.exit_status_ready.return_value = False
mock_select.select.return_value = ([], [], [True])
@@ -288,6 +308,87 @@ class SSHRunTestCase(unittest.TestCase):
self.fake_session.exit_status_ready.return_value = False
self.assertRaises(ssh.SSHTimeout, self.test_client.run, "cmd")
+ @mock.patch("yardstick.ssh.open", create=True)
+ def test__put_file_shell(self, mock_open):
+ with mock.patch.object(self.test_client, "run") as run_mock:
+ self.test_client._put_file_shell("localfile", "remotefile", 0o42)
+ run_mock.assert_called_once_with(
+ 'cat > "remotefile"&& chmod -- 042 "remotefile"',
+ stdin=mock_open.return_value.__enter__.return_value)
+
+ @mock.patch("yardstick.ssh.open", create=True)
+ def test__put_file_shell_space(self, mock_open):
+ with mock.patch.object(self.test_client, "run") as run_mock:
+ self.test_client._put_file_shell("localfile",
+ "filename with space", 0o42)
+ run_mock.assert_called_once_with(
+ 'cat > "filename with space"&& chmod -- 042 "filename with '
+ 'space"',
+ stdin=mock_open.return_value.__enter__.return_value)
+
+ @mock.patch("yardstick.ssh.open", create=True)
+ def test__put_file_shell_tilde(self, mock_open):
+ with mock.patch.object(self.test_client, "run") as run_mock:
+ self.test_client._put_file_shell("localfile", "~/remotefile", 0o42)
+ run_mock.assert_called_once_with(
+ 'cat > ~/"remotefile"&& chmod -- 042 ~/"remotefile"',
+ stdin=mock_open.return_value.__enter__.return_value)
+
+ @mock.patch("yardstick.ssh.open", create=True)
+ def test__put_file_shell_tilde_spaces(self, mock_open):
+ with mock.patch.object(self.test_client, "run") as run_mock:
+ self.test_client._put_file_shell("localfile", "~/file with space",
+ 0o42)
+ run_mock.assert_called_once_with(
+ 'cat > ~/"file with space"&& chmod -- 042 ~/"file with space"',
+ stdin=mock_open.return_value.__enter__.return_value)
+
+ @mock.patch("yardstick.ssh.os.stat")
+ def test__put_file_sftp(self, mock_stat):
+ sftp = self.fake_client.open_sftp.return_value = mock.MagicMock()
+ sftp.__enter__.return_value = sftp
+
+ mock_stat.return_value = os.stat_result([0o753] + [0] * 9)
+
+ self.test_client._put_file_sftp("localfile", "remotefile")
+
+ sftp.put.assert_called_once_with("localfile", "remotefile")
+ mock_stat.assert_called_once_with("localfile")
+ sftp.chmod.assert_called_once_with("remotefile", 0o753)
+ sftp.__exit__.assert_called_once_with(None, None, None)
+
+ def test__put_file_sftp_mode(self):
+ sftp = self.fake_client.open_sftp.return_value = mock.MagicMock()
+ sftp.__enter__.return_value = sftp
+
+ self.test_client._put_file_sftp("localfile", "remotefile", mode=0o753)
+
+ sftp.put.assert_called_once_with("localfile", "remotefile")
+ sftp.chmod.assert_called_once_with("remotefile", 0o753)
+ sftp.__exit__.assert_called_once_with(None, None, None)
+
+ def test_put_file_SSHException(self):
+ exc = ssh.paramiko.SSHException
+ self.test_client._put_file_sftp = mock.Mock(side_effect=exc())
+ self.test_client._put_file_shell = mock.Mock()
+
+ self.test_client.put_file("foo", "bar", 42)
+ self.test_client._put_file_sftp.assert_called_once_with("foo", "bar",
+ mode=42)
+ self.test_client._put_file_shell.assert_called_once_with("foo", "bar",
+ mode=42)
+
+ def test_put_file_socket_error(self):
+ exc = socket.error
+ self.test_client._put_file_sftp = mock.Mock(side_effect=exc())
+ self.test_client._put_file_shell = mock.Mock()
+
+ self.test_client.put_file("foo", "bar", 42)
+ self.test_client._put_file_sftp.assert_called_once_with("foo", "bar",
+ mode=42)
+ self.test_client._put_file_shell.assert_called_once_with("foo", "bar",
+ mode=42)
+
def main():
unittest.main()
diff --git a/tools/yardstick-img-lxd-modify b/tools/yardstick-img-lxd-modify
index 31194554c..4ca4eb489 100755
--- a/tools/yardstick-img-lxd-modify
+++ b/tools/yardstick-img-lxd-modify
@@ -32,21 +32,22 @@ die() {
exit 1
}
-test $# -eq 1 || die "no image specific script as argument"
+test $# -eq 1 -o $# -eq 2 || die "no image specific script as argument"
test $(id -u) -eq 0 || die "should invoke using sudo"
cmd=$1
+RELEASE=$2
test -x $cmd
mountdir="/mnt/yardstick"
workspace=${WORKSPACE:-"/tmp/workspace/yardstick"}
host=${HOST:-"cloud-images.ubuntu.com"}
-release=${RELEASE:-"trusty"}
+release=${RELEASE:-"xenial"}
image_path="${release}/current/${release}-server-cloudimg-amd64-root.tar.gz"
image_url=${IMAGE_URL:-"https://${host}/${image_path}"}
md5sums_path="${release}/current/MD5SUMS"
md5sums_url=${MD5SUMS_URL:-"https://${host}/${md5sums_path}"}
-imgfile="${workspace}/yardstick-${release}-server.tar.gz"
+imgfile="${workspace}/yardstick-image.tar.gz"
filename=$(basename $image_url)
# download and checksum base image, conditionally if local copy is outdated
diff --git a/tools/yardstick-img-modify b/tools/yardstick-img-modify
index 07f10b3ce..68ce6e223 100755
--- a/tools/yardstick-img-modify
+++ b/tools/yardstick-img-modify
@@ -32,21 +32,22 @@ die() {
exit 1
}
-test $# -eq 1 || die "no image specific script as argument"
+test $# -eq 1 -o $# -eq 2 || die "no image specific script as argument"
test $(id -u) -eq 0 || die "should invoke using sudo"
cmd=$1
+RELEASE=$2
test -x $cmd
mountdir="/mnt/yardstick"
workspace=${WORKSPACE:-"/tmp/workspace/yardstick"}
host=${HOST:-"cloud-images.ubuntu.com"}
-release=${RELEASE:-"trusty"}
+release=${RELEASE:-"xenial"}
image_path="${release}/current/${release}-server-cloudimg-${YARD_IMG_ARCH}-disk1.img"
image_url=${IMAGE_URL:-"https://${host}/${image_path}"}
md5sums_path="${release}/current/MD5SUMS"
md5sums_url=${MD5SUMS_URL:-"https://${host}/${md5sums_path}"}
-imgfile="${workspace}/yardstick-${release}-server.img"
+imgfile="${workspace}/yardstick-image.img"
raw_imgfile="${workspace}/yardstick-${release}-server.raw"
filename=$(basename $image_url)
@@ -151,9 +152,15 @@ cleanup() {
mount | grep $mountdir/proc && umount $mountdir/proc
mount | grep $mountdir && umount $mountdir
mount | grep "/mnt/vivid" && umount "/mnt/vivid"
+
if [ -f $raw_imgfile ]; then
+ #kpartx -dv $raw_imgfile sometimes failed, we should checked it agein.
+ #if [ -z "$(kpartx -l $raw_imgfile | grep 'loop deleted')" ]; then
+ # kpartx -dv $raw_imgfile
+ #fi
kpartx -dv $raw_imgfile || true
fi
+
rm -f $raw_imgfile
rm -rf $mountdir
}
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/contexts/node.py b/yardstick/benchmark/contexts/node.py
index c4e603a46..78bce8259 100644
--- a/yardstick/benchmark/contexts/node.py
+++ b/yardstick/benchmark/contexts/node.py
@@ -35,9 +35,9 @@ class NodeContext(Context):
def init(self, attrs):
'''initializes itself from the supplied arguments'''
self.name = attrs["name"]
- self.file_path = attrs.get("file", "")
+ self.file_path = attrs.get("file", "pod.yaml")
if not os.path.exists(self.file_path):
- self.file_path = YARDSTICK_ROOT_PATH + self.file_path
+ self.file_path = os.path.join(YARDSTICK_ROOT_PATH, self.file_path)
LOG.info("Parsing pod file: %s", self.file_path)
@@ -83,7 +83,7 @@ class NodeContext(Context):
return None
elif len(nodes) > 1:
LOG.error("Duplicate nodes!!!")
- LOG.error("Nodes: %r" % nodes)
+ LOG.error("Nodes: %r", nodes)
sys.exit(-1)
# A clone is created in order to avoid affecting the
diff --git a/yardstick/benchmark/runners/arithmetic.py b/yardstick/benchmark/runners/arithmetic.py
index 74a236f44..69ea915a1 100755
--- a/yardstick/benchmark/runners/arithmetic.py
+++ b/yardstick/benchmark/runners/arithmetic.py
@@ -93,7 +93,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
if aborted.is_set():
break
- LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
+ LOG.debug("runner=%(runner)s seq=%(sequence)s START",
{"runner": runner_cfg["runner_id"], "sequence": sequence})
for i, value in enumerate(comb_values):
@@ -109,7 +109,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
if sla_action == "assert":
raise
elif sla_action == "monitor":
- LOG.warning("SLA validation failed: %s" % assertion.args)
+ LOG.warning("SLA validation failed: %s", assertion.args)
errors = assertion.args
except Exception as e:
errors = traceback.format_exc()
@@ -129,7 +129,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
queue.put(record)
- LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
+ LOG.debug("runner=%(runner)s seq=%(sequence)s END",
{"runner": runner_cfg["runner_id"], "sequence": sequence})
sequence += 1
diff --git a/yardstick/benchmark/runners/base.py b/yardstick/benchmark/runners/base.py
index 23749924f..8f3f75fa1 100755
--- a/yardstick/benchmark/runners/base.py
+++ b/yardstick/benchmark/runners/base.py
@@ -63,7 +63,7 @@ def _execute_shell_command(command):
except Exception:
exitcode = -1
output = traceback.format_exc()
- log.error("exec command '%s' error:\n " % command)
+ log.error("exec command '%s' error:\n ", command)
log.error(traceback.format_exc())
return exitcode, output
@@ -76,10 +76,10 @@ def _single_action(seconds, command, queue):
log.debug("single action: executing command: '%s'", command)
ret_code, data = _execute_shell_command(command)
if ret_code < 0:
- log.error("single action error! command:%s" % command)
+ log.error("single action error! command:%s", command)
queue.put({'single-action-data': data})
return
- log.debug("single action data: \n%s" % data)
+ log.debug("single action data: \n%s", data)
queue.put({'single-action-data': data})
@@ -96,7 +96,7 @@ def _periodic_action(interval, command, queue):
log.error("periodic action error! command:%s", command)
queue.put({'periodic-action-data': data})
break
- log.debug("periodic action data: \n%s" % data)
+ log.debug("periodic action data: \n%s", data)
queue.put({'periodic-action-data': data})
@@ -127,7 +127,7 @@ class Runner(object):
"""
# if there is no runner, start the output serializer subprocess
if len(Runner.runners) == 0:
- log.debug("Starting dump process file '%s'" %
+ log.debug("Starting dump process file '%s'",
config["output_filename"])
Runner.queue = multiprocessing.Queue()
Runner.dump_process = multiprocessing.Process(
@@ -196,13 +196,13 @@ class Runner(object):
'''run a potentially configured post-stop action'''
if "post-stop-action" in self.config:
command = self.config["post-stop-action"]["command"]
- log.debug("post stop action: command: '%s'" % command)
+ log.debug("post stop action: command: '%s'", command)
ret_code, data = _execute_shell_command(command)
if ret_code < 0:
log.error("post action error! command:%s", command)
self.result_queue.put({'post-stop-action-data': data})
return
- log.debug("post-stop data: \n%s" % data)
+ log.debug("post-stop data: \n%s", data)
self.result_queue.put({'post-stop-action-data': data})
def run(self, scenario_cfg, context_cfg):
@@ -219,13 +219,13 @@ class Runner(object):
# run a potentially configured pre-start action
if "pre-start-action" in self.config:
command = self.config["pre-start-action"]["command"]
- log.debug("pre start action: command: '%s'" % command)
+ log.debug("pre start action: command: '%s'", command)
ret_code, data = _execute_shell_command(command)
if ret_code < 0:
log.error("pre-start action error! command:%s", command)
self.result_queue.put({'pre-start-action-data': data})
return
- log.debug("pre-start data: \n%s" % data)
+ log.debug("pre-start data: \n%s", data)
self.result_queue.put({'pre-start-action-data': data})
if "single-shot-action" in self.config:
diff --git a/yardstick/benchmark/runners/duration.py b/yardstick/benchmark/runners/duration.py
index 1f51f513f..1412c0caa 100644
--- a/yardstick/benchmark/runners/duration.py
+++ b/yardstick/benchmark/runners/duration.py
@@ -58,7 +58,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
start = time.time()
while True:
- LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
+ LOG.debug("runner=%(runner)s seq=%(sequence)s START",
{"runner": runner_cfg["runner_id"], "sequence": sequence})
data = {}
@@ -71,7 +71,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
if sla_action == "assert":
raise
elif sla_action == "monitor":
- LOG.warning("SLA validation failed: %s" % assertion.args)
+ LOG.warning("SLA validation failed: %s", assertion.args)
errors = assertion.args
except Exception as e:
errors = traceback.format_exc()
@@ -91,7 +91,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
queue.put(record)
- LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
+ LOG.debug("runner=%(runner)s seq=%(sequence)s END",
{"runner": runner_cfg["runner_id"], "sequence": sequence})
sequence += 1
diff --git a/yardstick/benchmark/runners/iteration.py b/yardstick/benchmark/runners/iteration.py
index b23b32b08..3a839b65f 100644
--- a/yardstick/benchmark/runners/iteration.py
+++ b/yardstick/benchmark/runners/iteration.py
@@ -60,7 +60,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
if "run" in run_step:
while True:
- LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
+ LOG.debug("runner=%(runner)s seq=%(sequence)s START",
{"runner": runner_cfg["runner_id"],
"sequence": sequence})
@@ -74,7 +74,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
if sla_action == "assert":
raise
elif sla_action == "monitor":
- LOG.warning("SLA validation failed: %s" % assertion.args)
+ LOG.warning("SLA validation failed: %s", assertion.args)
errors = assertion.args
except Exception as e:
errors = traceback.format_exc()
@@ -94,7 +94,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
queue.put(record)
- LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
+ LOG.debug("runner=%(runner)s seq=%(sequence)s END",
{"runner": runner_cfg["runner_id"],
"sequence": sequence})
diff --git a/yardstick/benchmark/runners/sequence.py b/yardstick/benchmark/runners/sequence.py
index fe53412ca..3b06e2a36 100644
--- a/yardstick/benchmark/runners/sequence.py
+++ b/yardstick/benchmark/runners/sequence.py
@@ -67,7 +67,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
for value in sequence_values:
options[arg_name] = value
- LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
+ LOG.debug("runner=%(runner)s seq=%(sequence)s START",
{"runner": runner_cfg["runner_id"], "sequence": sequence})
data = {}
@@ -80,7 +80,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
if sla_action == "assert":
raise
elif sla_action == "monitor":
- LOG.warning("SLA validation failed: %s" % assertion.args)
+ LOG.warning("SLA validation failed: %s", assertion.args)
errors = assertion.args
except Exception as e:
errors = traceback.format_exc()
@@ -100,7 +100,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg,
queue.put(record)
- LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
+ LOG.debug("runner=%(runner)s seq=%(sequence)s END",
{"runner": runner_cfg["runner_id"], "sequence": sequence})
sequence += 1
diff --git a/yardstick/benchmark/scenarios/availability/actionrollbackers.py b/yardstick/benchmark/scenarios/availability/actionrollbackers.py
index 4b732a10c..38f57d476 100644
--- a/yardstick/benchmark/scenarios/availability/actionrollbackers.py
+++ b/yardstick/benchmark/scenarios/availability/actionrollbackers.py
@@ -28,8 +28,8 @@ class AttackerRollbacker(ActionRollbacker):
def rollback(self):
LOG.debug(
- "\033[93m recovering attacker %s \033[0m"
- % (self.underlyingAttacker.key))
+ "\033[93m recovering attacker %s \033[0m",
+ self.underlyingAttacker.key)
self.underlyingAttacker.recover()
@@ -40,6 +40,6 @@ class OperationRollbacker(ActionRollbacker):
def rollback(self):
LOG.debug(
- "\033[93m rollback operation %s \033[0m"
- % (self.underlyingOperation.key))
+ "\033[93m rollback operation %s \033[0m",
+ self.underlyingOperation.key)
self.underlyingOperation.rollback()
diff --git a/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py b/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py
index 6561f6b65..e88fed636 100644
--- a/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py
+++ b/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py
@@ -24,7 +24,7 @@ def _execute_shell_command(command, stdin=None):
except Exception:
exitcode = -1
output = traceback.format_exc()
- LOG.error("exec command '%s' error:\n " % command)
+ LOG.error("exec command '%s' error:\n ", command)
LOG.error(traceback.format_exc())
return exitcode, output
@@ -34,7 +34,7 @@ class BaremetalAttacker(BaseAttacker):
__attacker_type__ = 'bare-metal-down'
def setup(self):
- LOG.debug("config:%s context:%s" % (self._config, self._context))
+ LOG.debug("config:%s context:%s", self._config, self._context)
host = self._context.get(self._config['host'], None)
ip = host.get("ip", None)
user = host.get("user", "root")
@@ -61,14 +61,15 @@ class BaremetalAttacker(BaseAttacker):
self.setup_done = True
def check(self):
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/sh -s {0} -W 10".format(self.host_ip),
- stdin=open(self.check_script, "r"))
+ with open(self.check_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/sh -s {0} -W 10".format(self.host_ip),
+ stdin=stdin_file)
- LOG.debug("check ret: %s out:%s err:%s" %
- (exit_status, stdout, stderr))
+ LOG.debug("check ret: %s out:%s err:%s",
+ exit_status, stdout, stderr)
if not stdout or "running" not in stdout:
- LOG.info("the host (ipmi_ip:%s) is not running!" % self.ipmi_ip)
+ LOG.info("the host (ipmi_ip:%s) is not running!", self.ipmi_ip)
return False
return True
@@ -76,8 +77,8 @@ class BaremetalAttacker(BaseAttacker):
def inject_fault(self):
exit_status, stdout, stderr = self.connection.execute(
"shutdown -h now")
- LOG.debug("inject fault ret: %s out:%s err:%s" %
- (exit_status, stdout, stderr))
+ LOG.debug("inject fault ret: %s out:%s err:%s",
+ exit_status, stdout, stderr)
if not exit_status:
LOG.info("inject fault success")
@@ -91,17 +92,18 @@ class BaremetalAttacker(BaseAttacker):
ssh_port = host.get("ssh_port", ssh.DEFAULT_PORT)
pwd = host.get("pwd", None)
- LOG.debug("jump_host ip:%s user:%s" % (ip, user))
+ LOG.debug("jump_host ip:%s user:%s", ip, user)
self.jump_connection = ssh.SSH(user, ip, password=pwd,
port=ssh_port)
self.jump_connection.wait(timeout=600)
LOG.debug("ssh jump host success!")
if self.jump_connection is not None:
- exit_status, stdout, stderr = self.jump_connection.execute(
- "/bin/bash -s {0} {1} {2} {3}".format(
- self.ipmi_ip, self.ipmi_user, self.ipmi_pwd, "on"),
- stdin=open(self.recovery_script, "r"))
+ with open(self.recovery_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.jump_connection.execute(
+ "/bin/bash -s {0} {1} {2} {3}".format(
+ self.ipmi_ip, self.ipmi_user, self.ipmi_pwd, "on"),
+ stdin=stdin_file)
else:
exit_status, stdout = _execute_shell_command(
"/bin/bash -s {0} {1} {2} {3}".format(
diff --git a/yardstick/benchmark/scenarios/availability/attacker/attacker_general.py b/yardstick/benchmark/scenarios/availability/attacker/attacker_general.py
index 5e7716e49..595067a95 100644
--- a/yardstick/benchmark/scenarios/availability/attacker/attacker_general.py
+++ b/yardstick/benchmark/scenarios/availability/attacker/attacker_general.py
@@ -20,7 +20,7 @@ class GeneralAttacker(BaseAttacker):
__attacker_type__ = 'general-attacker'
def setup(self):
- LOG.debug("config:%s context:%s" % (self._config, self._context))
+ LOG.debug("config:%s context:%s", self._config, self._context)
host = self._context.get(self._config['host'], None)
ip = host.get("ip", None)
user = host.get("user", "root")
@@ -65,13 +65,15 @@ class GeneralAttacker(BaseAttacker):
if "action_parameter" in self._config:
LOG.debug("the shell command is: {0}".format(self.action_param))
- exit_status, stdout, stderr = self.connection.execute(
- self.action_param,
- stdin=open(self.inject_script, "r"))
+ with open(self.inject_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ self.action_param,
+ stdin=stdin_file)
else:
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/bash -s ",
- stdin=open(self.inject_script, "r"))
+ with open(self.inject_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/bash -s ",
+ stdin=stdin_file)
LOG.debug("the inject_fault's exit status is: {0}".format(exit_status))
if exit_status == 0:
@@ -79,16 +81,18 @@ class GeneralAttacker(BaseAttacker):
.format(stdout))
else:
LOG.error(
- "the inject_fault's error, stdout:%s, stderr:%s" %
- (stdout, stderr))
+ "the inject_fault's error, stdout:%s, stderr:%s",
+ stdout, stderr)
def recover(self):
if "rollback_parameter" in self._config:
LOG.debug("the shell command is: {0}".format(self.rollback_param))
- exit_status, stdout, stderr = self.connection.execute(
- self.rollback_param,
- stdin=open(self.recovery_script, "r"))
+ with open(self.recovery_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ self.rollback_param,
+ stdin=stdin_file)
else:
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/bash -s ",
- stdin=open(self.recovery_script, "r"))
+ with open(self.recovery_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/bash -s ",
+ stdin=stdin_file)
diff --git a/yardstick/benchmark/scenarios/availability/attacker/attacker_process.py b/yardstick/benchmark/scenarios/availability/attacker/attacker_process.py
index 0a844f56c..1d190a160 100644
--- a/yardstick/benchmark/scenarios/availability/attacker/attacker_process.py
+++ b/yardstick/benchmark/scenarios/availability/attacker/attacker_process.py
@@ -19,7 +19,7 @@ class ProcessAttacker(BaseAttacker):
__attacker_type__ = 'kill-process'
def setup(self):
- LOG.debug("config:%s context:%s" % (self._config, self._context))
+ LOG.debug("config:%s context:%s", self._config, self._context)
host = self._context.get(self._config['host'], None)
ip = host.get("ip", None)
user = host.get("user", "root")
@@ -45,25 +45,28 @@ class ProcessAttacker(BaseAttacker):
self.setup_done = True
def check(self):
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/sh -s {0}".format(self.service_name),
- stdin=open(self.check_script, "r"))
+ with open(self.check_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/sh -s {0}".format(self.service_name),
+ stdin=stdin_file)
if stdout and "running" in stdout:
LOG.info("check the envrioment success!")
return True
else:
LOG.error(
- "the host envrioment is error, stdout:%s, stderr:%s" %
- (stdout, stderr))
+ "the host envrioment is error, stdout:%s, stderr:%s",
+ stdout, stderr)
return False
def inject_fault(self):
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/sh -s {0}".format(self.service_name),
- stdin=open(self.inject_script, "r"))
+ with open(self.inject_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/sh -s {0}".format(self.service_name),
+ stdin=stdin_file)
def recover(self):
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/sh -s {0} ".format(self.service_name),
- stdin=open(self.recovery_script, "r"))
+ with open(self.recovery_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/sh -s {0} ".format(self.service_name),
+ stdin=stdin_file)
diff --git a/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py b/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py
index 78276efa2..f96e57728 100644
--- a/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py
+++ b/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py
@@ -26,7 +26,7 @@ class AttackerMgr(object):
self._attacker_list = []
def init_attackers(self, attacker_cfgs, context):
- LOG.debug("attackerMgr confg: %s" % attacker_cfgs)
+ LOG.debug("attackerMgr confg: %s", attacker_cfgs)
for cfg in attacker_cfgs:
attacker_cls = BaseAttacker.get_attacker_cls(cfg)
diff --git a/yardstick/benchmark/scenarios/availability/director.py b/yardstick/benchmark/scenarios/availability/director.py
index 267933dd0..104c68380 100644
--- a/yardstick/benchmark/scenarios/availability/director.py
+++ b/yardstick/benchmark/scenarios/availability/director.py
@@ -63,7 +63,7 @@ class Director(object):
def createActionPlayer(self, type, key):
LOG.debug(
- "the type of current action is %s, the key is %s" % (type, key))
+ "the type of current action is %s, the key is %s", type, key)
if type == ActionType.ATTACKER:
return actionplayers.AttackerPlayer(self.attackerMgr[key])
if type == ActionType.MONITOR:
@@ -77,13 +77,13 @@ class Director(object):
def createActionRollbacker(self, type, key):
LOG.debug(
- "the type of current action is %s, the key is %s" % (type, key))
+ "the type of current action is %s, the key is %s", type, key)
if type == ActionType.ATTACKER:
return actionrollbackers.AttackerRollbacker(self.attackerMgr[key])
if type == ActionType.OPERATION:
return actionrollbackers.OperationRollbacker(
self.operationMgr[key])
- LOG.debug("no rollbacker created for %s" % (key))
+ LOG.debug("no rollbacker created for %s", key)
def verify(self):
result = True
diff --git a/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py b/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py
index d26c99c75..38d1c4e5c 100644
--- a/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py
+++ b/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py
@@ -27,7 +27,7 @@ class MonitorMgr(object):
self._monitor_list = []
def init_monitors(self, monitor_cfgs, context):
- LOG.debug("monitorMgr config: %s" % monitor_cfgs)
+ LOG.debug("monitorMgr config: %s", monitor_cfgs)
for monitor_cfg in monitor_cfgs:
monitor_type = monitor_cfg["monitor_type"]
@@ -87,7 +87,7 @@ class BaseMonitor(multiprocessing.Process):
return os.path.join(base_path, path)
def run(self):
- LOG.debug("config:%s context:%s" % (self._config, self._context))
+ LOG.debug("config:%s context:%s", self._config, self._context)
self.setup()
monitor_time = self._config.get("monitor_time", 0)
@@ -140,7 +140,7 @@ class BaseMonitor(multiprocessing.Process):
def wait_monitor(self):
self.join()
self._result = self._queue.get()
- LOG.debug("the monitor result:%s" % self._result)
+ LOG.debug("the monitor result:%s", self._result)
def setup(self): # pragma: no cover
pass
diff --git a/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py b/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py
index b55cc3134..cd33e6188 100644
--- a/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py
+++ b/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py
@@ -24,7 +24,7 @@ def _execute_shell_command(command):
except Exception:
exitcode = -1
output = traceback.format_exc()
- LOG.error("exec command '%s' error:\n " % command)
+ LOG.error("exec command '%s' error:\n ", command)
LOG.error(traceback.format_exc())
return exitcode, output
@@ -58,12 +58,13 @@ class MonitorOpenstackCmd(basemonitor.BaseMonitor):
def monitor_func(self):
exit_status = 0
if self.connection:
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/bash -s '{0}'".format(self.cmd),
- stdin=open(self.check_script, "r"))
+ with open(self.check_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/bash -s '{0}'".format(self.cmd),
+ stdin=stdin_file)
- LOG.debug("the ret stats: %s stdout: %s stderr: %s" %
- (exit_status, stdout, stderr))
+ LOG.debug("the ret stats: %s stdout: %s stderr: %s",
+ exit_status, stdout, stderr)
else:
exit_status, stdout = _execute_shell_command(self.cmd)
if exit_status:
@@ -72,10 +73,10 @@ class MonitorOpenstackCmd(basemonitor.BaseMonitor):
def verify_SLA(self):
outage_time = self._result.get('outage_time', None)
- LOG.debug("the _result:%s" % self._result)
+ LOG.debug("the _result:%s", self._result)
max_outage_time = self._config["sla"]["max_outage_time"]
if outage_time > max_outage_time:
- LOG.info("SLA failure: %f > %f" % (outage_time, max_outage_time))
+ LOG.info("SLA failure: %f > %f", outage_time, max_outage_time)
return False
else:
LOG.info("the sla is passed")
diff --git a/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py b/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py
index f9ddb2505..461a2ded5 100644
--- a/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py
+++ b/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py
@@ -48,27 +48,29 @@ class GeneralMonitor(basemonitor.BaseMonitor):
def monitor_func(self):
if "parameter" in self._config:
- exit_status, stdout, stderr = self.connection.execute(
- self.cmd_param,
- stdin=open(self.monitor_script, "r"))
+ with open(self.monitor_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ self.cmd_param,
+ stdin=stdin_file)
else:
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/bash -s ",
- stdin=open(self.monitor_script, "r"))
+ with open(self.monitor_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/bash -s ",
+ stdin=stdin_file)
if exit_status:
return False
return True
def verify_SLA(self):
- LOG.debug("the _result:%s" % self._result)
+ LOG.debug("the _result:%s", self._result)
outage_time = self._result.get('outage_time', None)
max_outage_time = self._config["sla"]["max_outage_time"]
if outage_time is None:
LOG.error("There is no outage_time in monitor result.")
return False
if outage_time > max_outage_time:
- LOG.error("SLA failure: %f > %f" % (outage_time, max_outage_time))
+ LOG.error("SLA failure: %f > %f", outage_time, max_outage_time)
return False
else:
return True
diff --git a/yardstick/benchmark/scenarios/availability/monitor/monitor_process.py b/yardstick/benchmark/scenarios/availability/monitor/monitor_process.py
index 403ec4d37..5f492ad69 100644
--- a/yardstick/benchmark/scenarios/availability/monitor/monitor_process.py
+++ b/yardstick/benchmark/scenarios/availability/monitor/monitor_process.py
@@ -35,21 +35,22 @@ class MonitorProcess(basemonitor.BaseMonitor):
self.process_name = self._config["process_name"]
def monitor_func(self):
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/sh -s {0}".format(self.process_name),
- stdin=open(self.check_script, "r"))
+ with open(self.check_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/sh -s {0}".format(self.process_name),
+ stdin=stdin_file)
if not stdout or int(stdout) <= 0:
- LOG.info("the process (%s) is not running!" % self.process_name)
+ LOG.info("the process (%s) is not running!", self.process_name)
return False
return True
def verify_SLA(self):
- LOG.debug("the _result:%s" % self._result)
+ LOG.debug("the _result:%s", self._result)
outage_time = self._result.get('outage_time', None)
max_outage_time = self._config["sla"]["max_recover_time"]
if outage_time > max_outage_time:
- LOG.error("SLA failure: %f > %f" % (outage_time, max_outage_time))
+ LOG.error("SLA failure: %f > %f", outage_time, max_outage_time)
return False
else:
return True
diff --git a/yardstick/benchmark/scenarios/availability/operation/baseoperation.py b/yardstick/benchmark/scenarios/availability/operation/baseoperation.py
index e776e87ae..80efd1b02 100644
--- a/yardstick/benchmark/scenarios/availability/operation/baseoperation.py
+++ b/yardstick/benchmark/scenarios/availability/operation/baseoperation.py
@@ -26,7 +26,7 @@ class OperationMgr(object):
self._operation_list = []
def init_operations(self, operation_cfgs, context):
- LOG.debug("operationMgr confg: %s" % operation_cfgs)
+ LOG.debug("operationMgr confg: %s", operation_cfgs)
for cfg in operation_cfgs:
operation_type = cfg['operation_type']
operation_cls = BaseOperation.get_operation_cls(operation_type)
diff --git a/yardstick/benchmark/scenarios/availability/operation/operation_general.py b/yardstick/benchmark/scenarios/availability/operation/operation_general.py
index aa28472f7..c82df836d 100644
--- a/yardstick/benchmark/scenarios/availability/operation/operation_general.py
+++ b/yardstick/benchmark/scenarios/availability/operation/operation_general.py
@@ -19,7 +19,7 @@ class GeneralOperaion(BaseOperation):
__operation__type__ = "general-operation"
def setup(self):
- LOG.debug("config:%s context:%s" % (self._config, self._context))
+ LOG.debug("config:%s context:%s", self._config, self._context)
host = self._context.get(self._config['host'], None)
ip = host.get("ip", None)
user = host.get("user", "root")
@@ -55,27 +55,31 @@ class GeneralOperaion(BaseOperation):
def run(self):
if "action_parameter" in self._config:
- exit_status, stdout, stderr = self.connection.execute(
- self.action_param,
- stdin=open(self.action_script, "r"))
+ with open(self.action_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ self.action_param,
+ stdin=stdin_file)
else:
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/sh -s ",
- stdin=open(self.action_script, "r"))
+ with open(self.action_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/sh -s ",
+ stdin=stdin_file)
if exit_status == 0:
LOG.debug("success,the operation's output is: {0}".format(stdout))
else:
LOG.error(
- "the operation's error, stdout:%s, stderr:%s" %
- (stdout, stderr))
+ "the operation's error, stdout:%s, stderr:%s",
+ stdout, stderr)
def rollback(self):
if "rollback_parameter" in self._config:
- exit_status, stdout, stderr = self.connection.execute(
- self.rollback_param,
- stdin=open(self.rollback_script, "r"))
+ with open(self.rollback_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ self.rollback_param,
+ stdin=stdin_file)
else:
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/sh -s ",
- stdin=open(self.rollback_script, "r"))
+ with open(self.rollback_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/sh -s ",
+ stdin=stdin_file)
diff --git a/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py b/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py
index 1bdb9f2c2..a24f26e81 100644
--- a/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py
+++ b/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py
@@ -26,7 +26,7 @@ class ResultCheckerMgr(object):
self._result_checker_list = []
def init_ResultChecker(self, resultchecker_cfgs, context):
- LOG.debug("resultcheckerMgr confg: %s" % resultchecker_cfgs)
+ LOG.debug("resultcheckerMgr confg: %s", resultchecker_cfgs)
for cfg in resultchecker_cfgs:
resultchecker_type = cfg['checker_type']
diff --git a/yardstick/benchmark/scenarios/availability/result_checker/result_checker_general.py b/yardstick/benchmark/scenarios/availability/result_checker/result_checker_general.py
index ae896c2b2..275aff076 100644
--- a/yardstick/benchmark/scenarios/availability/result_checker/result_checker_general.py
+++ b/yardstick/benchmark/scenarios/availability/result_checker/result_checker_general.py
@@ -20,7 +20,7 @@ class GeneralResultChecker(BaseResultChecker):
__result_checker__type__ = "general-result-checker"
def setup(self):
- LOG.debug("config:%s context:%s" % (self._config, self._context))
+ LOG.debug("config:%s context:%s", self._config, self._context)
host = self._context.get(self._config['host'], None)
ip = host.get("ip", None)
user = host.get("user", "root")
@@ -53,21 +53,23 @@ class GeneralResultChecker(BaseResultChecker):
def verify(self):
if "parameter" in self._config:
- exit_status, stdout, stderr = self.connection.execute(
- self.shell_cmd,
- stdin=open(self.verify_script, "r"))
+ with open(self.verify_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ self.shell_cmd,
+ stdin=stdin_file)
LOG.debug("action script of the operation is: {0}"
.format(self.verify_script))
LOG.debug("action parameter the of operation is: {0}"
.format(self.shell_cmd))
else:
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/bash -s ",
- stdin=open(self.verify_script, "r"))
+ with open(self.verify_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/bash -s ",
+ stdin=stdin_file)
LOG.debug("action script of the operation is: {0}"
.format(self.verify_script))
- LOG.debug("exit_status ,stdout : {0} ,{1}".format(exit_status, stdout))
+ LOG.debug("exit_status ,stdout : %s ,%s", exit_status, stdout)
if exit_status == 0 and stdout:
self.actualResult = stdout
LOG.debug("verifying resultchecker: {0}".format(self.key))
@@ -104,6 +106,6 @@ class GeneralResultChecker(BaseResultChecker):
LOG.error(stderr)
LOG.debug(
- "verifying resultchecker: {0},the result is : {1}"
- .format(self.key, self.success))
+ "verifying resultchecker: %s,the result is : %s", self.key,
+ self.success)
return self.success
diff --git a/yardstick/benchmark/scenarios/availability/scenario_general.py b/yardstick/benchmark/scenarios/availability/scenario_general.py
index 0a128aa09..b064c6724 100644
--- a/yardstick/benchmark/scenarios/availability/scenario_general.py
+++ b/yardstick/benchmark/scenarios/availability/scenario_general.py
@@ -22,7 +22,7 @@ class ScenarioGeneral(base.Scenario):
def __init__(self, scenario_cfg, context_cfg):
LOG.debug(
- "scenario_cfg:%s context_cfg:%s" % (scenario_cfg, context_cfg))
+ "scenario_cfg:%s context_cfg:%s", scenario_cfg, context_cfg)
self.scenario_cfg = scenario_cfg
self.context_cfg = context_cfg
diff --git a/yardstick/benchmark/scenarios/availability/serviceha.py b/yardstick/benchmark/scenarios/availability/serviceha.py
index 10f2c4f45..46a197c3b 100755
--- a/yardstick/benchmark/scenarios/availability/serviceha.py
+++ b/yardstick/benchmark/scenarios/availability/serviceha.py
@@ -21,8 +21,8 @@ class ServiceHA(base.Scenario):
def __init__(self, scenario_cfg, context_cfg):
LOG.debug(
- "scenario_cfg:%s context_cfg:%s" %
- (scenario_cfg, context_cfg))
+ "scenario_cfg:%s context_cfg:%s",
+ scenario_cfg, context_cfg)
self.scenario_cfg = scenario_cfg
self.context_cfg = context_cfg
self.setup_done = False
diff --git a/yardstick/benchmark/scenarios/compute/cachestat.py b/yardstick/benchmark/scenarios/compute/cachestat.py
index 117702098..20786ff61 100644
--- a/yardstick/benchmark/scenarios/compute/cachestat.py
+++ b/yardstick/benchmark/scenarios/compute/cachestat.py
@@ -85,14 +85,13 @@ class CACHEstat(base.Scenario):
self.client.wait(timeout=600)
# copy scripts to host
- self.client.run("cat > ~/cache_stat.sh",
- stdin=open(self.target_script, 'rb'))
+ self.client._put_file_shell(self.target_script, '~/cache_stat.sh')
self.setup_done = True
def _execute_command(self, cmd):
"""Execute a command on server."""
- LOG.info("Executing: %s" % cmd)
+ LOG.info("Executing: %s", cmd)
status, stdout, stderr = self.client.execute(cmd)
if status:
raise RuntimeError("Failed executing command: ",
diff --git a/yardstick/benchmark/scenarios/compute/computecapacity.py b/yardstick/benchmark/scenarios/compute/computecapacity.py
index 9d7a923b1..7f0c58de1 100644
--- a/yardstick/benchmark/scenarios/compute/computecapacity.py
+++ b/yardstick/benchmark/scenarios/compute/computecapacity.py
@@ -49,8 +49,7 @@ class ComputeCapacity(base.Scenario):
self.client.wait(timeout=600)
# copy script to host
- self.client.run("cat > ~/computecapacity.sh",
- stdin=open(self.target_script, 'rb'))
+ self.client._put_file_shell(self.target_script, '~/computecapacity.sh')
self.setup_done = True
diff --git a/yardstick/benchmark/scenarios/compute/cpuload.py b/yardstick/benchmark/scenarios/compute/cpuload.py
index a7fae44ec..9d71038ef 100644
--- a/yardstick/benchmark/scenarios/compute/cpuload.py
+++ b/yardstick/benchmark/scenarios/compute/cpuload.py
@@ -96,7 +96,7 @@ class CPULoad(base.Scenario):
def _execute_command(self, cmd):
"""Execute a command on server."""
- LOG.info("Executing: %s" % cmd)
+ LOG.info("Executing: %s", cmd)
status, stdout, stderr = self.client.execute(cmd)
if status != 0:
raise RuntimeError("Failed executing command: ",
diff --git a/yardstick/benchmark/scenarios/compute/cyclictest.py b/yardstick/benchmark/scenarios/compute/cyclictest.py
index 6a1afe223..568e6e7df 100644
--- a/yardstick/benchmark/scenarios/compute/cyclictest.py
+++ b/yardstick/benchmark/scenarios/compute/cyclictest.py
@@ -69,14 +69,14 @@ class Cyclictest(base.Scenario):
rpm_dir = setup_options["rpm_dir"]
script_dir = setup_options["script_dir"]
image_dir = setup_options["image_dir"]
- LOG.debug("Send RPMs from %s to workspace %s" %
- (rpm_dir, self.WORKSPACE))
+ LOG.debug("Send RPMs from %s to workspace %s",
+ rpm_dir, self.WORKSPACE)
client.put(rpm_dir, self.WORKSPACE, recursive=True)
- LOG.debug("Send scripts from %s to workspace %s" %
- (script_dir, self.WORKSPACE))
+ LOG.debug("Send scripts from %s to workspace %s",
+ script_dir, self.WORKSPACE)
client.put(script_dir, self.WORKSPACE, recursive=True)
- LOG.debug("Send guest image from %s to workspace %s" %
- (image_dir, self.WORKSPACE))
+ LOG.debug("Send guest image from %s to workspace %s",
+ image_dir, self.WORKSPACE)
client.put(image_dir, self.WORKSPACE, recursive=True)
def _connect_host(self):
@@ -102,7 +102,7 @@ class Cyclictest(base.Scenario):
self.guest.wait(timeout=600)
def _run_setup_cmd(self, client, cmd):
- LOG.debug("Run cmd: %s" % cmd)
+ LOG.debug("Run cmd: %s", cmd)
status, stdout, stderr = client.execute(cmd)
if status:
if re.search(self.REBOOT_CMD_PATTERN, cmd):
@@ -154,8 +154,8 @@ class Cyclictest(base.Scenario):
self.target_script = pkg_resources.resource_filename(
"yardstick.benchmark.scenarios.compute",
Cyclictest.TARGET_SCRIPT)
- self.guest.run("cat > ~/cyclictest_benchmark.sh",
- stdin=open(self.target_script, "rb"))
+ self.guest._put_file_shell(
+ self.target_script, '~/cyclictest_benchmark.sh')
self.setup_done = True
diff --git a/yardstick/benchmark/scenarios/compute/lmbench.py b/yardstick/benchmark/scenarios/compute/lmbench.py
index 9ceb2484c..518840c09 100644
--- a/yardstick/benchmark/scenarios/compute/lmbench.py
+++ b/yardstick/benchmark/scenarios/compute/lmbench.py
@@ -87,12 +87,12 @@ class Lmbench(base.Scenario):
self.client.wait(timeout=600)
# copy scripts to host
- self.client.run("cat > ~/lmbench_latency.sh",
- stdin=open(self.latency_target_script, 'rb'))
- self.client.run("cat > ~/lmbench_bandwidth.sh",
- stdin=open(self.bandwidth_target_script, 'rb'))
- self.client.run("cat > ~/lmbench_latency_for_cache.sh",
- stdin=open(self.latency_for_cache_script, 'rb'))
+ self.client._put_file_shell(
+ self.latency_target_script, '~/lmbench_latency.sh')
+ self.client._put_file_shell(
+ self.bandwidth_target_script, '~/lmbench_bandwidth.sh')
+ self.client._put_file_shell(
+ self.latency_for_cache_script, '~/lmbench_latency_for_cache.sh')
self.setup_done = True
def run(self, result):
diff --git a/yardstick/benchmark/scenarios/compute/memload.py b/yardstick/benchmark/scenarios/compute/memload.py
index 48088f87c..e1ba93d02 100644
--- a/yardstick/benchmark/scenarios/compute/memload.py
+++ b/yardstick/benchmark/scenarios/compute/memload.py
@@ -61,7 +61,7 @@ class MEMLoad(base.Scenario):
def _execute_command(self, cmd):
"""Execute a command on server."""
- LOG.info("Executing: %s" % cmd)
+ LOG.info("Executing: %s", cmd)
status, stdout, stderr = self.client.execute(cmd)
if status:
raise RuntimeError("Failed executing command: ",
diff --git a/yardstick/benchmark/scenarios/compute/perf.py b/yardstick/benchmark/scenarios/compute/perf.py
index 6c827efc2..8f1a4d630 100644
--- a/yardstick/benchmark/scenarios/compute/perf.py
+++ b/yardstick/benchmark/scenarios/compute/perf.py
@@ -57,8 +57,7 @@ class Perf(base.Scenario):
self.client.wait(timeout=600)
# copy script to host
- self.client.run("cat > ~/perf_benchmark.sh",
- stdin=open(self.target_script, "rb"))
+ self.client._put_file_shell(self.target_script, '~/perf_benchmark.sh')
self.setup_done = True
diff --git a/yardstick/benchmark/scenarios/compute/ramspeed.py b/yardstick/benchmark/scenarios/compute/ramspeed.py
index bc33f8af2..db70af90b 100644
--- a/yardstick/benchmark/scenarios/compute/ramspeed.py
+++ b/yardstick/benchmark/scenarios/compute/ramspeed.py
@@ -97,10 +97,10 @@ class Ramspeed(base.Scenario):
self.client.wait(timeout=600)
# copy scripts to host
- self.client.run("cat > ~/ramspeed_mark_benchmark.sh",
- stdin=open(self.mark_target_script, 'rb'))
- self.client.run("cat > ~/ramspeed_mem_benchmark.sh",
- stdin=open(self.mem_target_script, 'rb'))
+ self.client._put_file_shell(
+ self.mark_target_script, '~/ramspeed_mark_benchmark.sh')
+ self.client._put_file_shell(
+ self.mem_target_script, '~/ramspeed_mem_benchmark.sh')
self.setup_done = True
def run(self, result):
diff --git a/yardstick/benchmark/scenarios/compute/unixbench.py b/yardstick/benchmark/scenarios/compute/unixbench.py
index e6299346f..b22be29c9 100644
--- a/yardstick/benchmark/scenarios/compute/unixbench.py
+++ b/yardstick/benchmark/scenarios/compute/unixbench.py
@@ -77,8 +77,8 @@ class Unixbench(base.Scenario):
self.client.wait(timeout=600)
# copy scripts to host
- self.client.run("cat > ~/unixbench_benchmark.sh",
- stdin=open(self.target_script, 'rb'))
+ self.client._put_file_shell(
+ self.target_script, '~/unixbench_benchmark.sh')
self.setup_done = True
diff --git a/yardstick/benchmark/scenarios/networking/netperf.py b/yardstick/benchmark/scenarios/networking/netperf.py
index 08901e12b..28f5bea56 100755
--- a/yardstick/benchmark/scenarios/networking/netperf.py
+++ b/yardstick/benchmark/scenarios/networking/netperf.py
@@ -85,8 +85,7 @@ class Netperf(base.Scenario):
self.client.wait(timeout=600)
# copy script to host
- self.client.run("cat > ~/netperf.sh",
- stdin=open(self.target_script, "rb"))
+ self.client._put_file_shell(self.target_script, '~/netperf.sh')
self.setup_done = True
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/benchmark/scenarios/networking/netutilization.py b/yardstick/benchmark/scenarios/networking/netutilization.py
index ecde7568e..1ea92cca3 100644
--- a/yardstick/benchmark/scenarios/networking/netutilization.py
+++ b/yardstick/benchmark/scenarios/networking/netutilization.py
@@ -83,7 +83,7 @@ class NetUtilization(base.Scenario):
def _execute_command(self, cmd):
"""Execute a command on target."""
- LOG.info("Executing: %s" % cmd)
+ LOG.info("Executing: %s", cmd)
status, stdout, stderr = self.client.execute(cmd)
if status:
raise RuntimeError("Failed executing command: ",
diff --git a/yardstick/benchmark/scenarios/networking/networkcapacity.py b/yardstick/benchmark/scenarios/networking/networkcapacity.py
index 438452e40..250f7eaf0 100644
--- a/yardstick/benchmark/scenarios/networking/networkcapacity.py
+++ b/yardstick/benchmark/scenarios/networking/networkcapacity.py
@@ -50,8 +50,7 @@ class NetworkCapacity(base.Scenario):
self.client.wait(timeout=600)
# copy script to host
- self.client.run("cat > ~/networkcapacity.sh",
- stdin=open(self.target_script, 'rb'))
+ self.client._put_file_shell(self.target_script, '~/networkcapacity.sh')
self.setup_done = True
diff --git a/yardstick/benchmark/scenarios/networking/ping.py b/yardstick/benchmark/scenarios/networking/ping.py
index 2becdaf36..6e49a1437 100644
--- a/yardstick/benchmark/scenarios/networking/ping.py
+++ b/yardstick/benchmark/scenarios/networking/ping.py
@@ -55,7 +55,7 @@ class Ping(base.Scenario):
self.connection = ssh.SSH(user, ip, key_filename=key_filename,
port=ssh_port)
- self.connection.wait()
+ self.connection.wait(timeout=600)
def run(self, result):
"""execute the benchmark"""
@@ -79,9 +79,10 @@ class Ping(base.Scenario):
target_vm = self.scenario_cfg['target']
LOG.debug("ping '%s' '%s'", options, dest)
- exit_status, stdout, stderr = self.connection.execute(
- "/bin/sh -s {0} {1}".format(dest, options),
- stdin=open(self.target_script, "r"))
+ with open(self.target_script, "r") as stdin_file:
+ exit_status, stdout, stderr = self.connection.execute(
+ "/bin/sh -s {0} {1}".format(dest, options),
+ stdin=stdin_file)
if exit_status != 0:
raise RuntimeError(stderr)
diff --git a/yardstick/benchmark/scenarios/networking/ping6.py b/yardstick/benchmark/scenarios/networking/ping6.py
index 9aa94c40c..f4d23ce7b 100644
--- a/yardstick/benchmark/scenarios/networking/ping6.py
+++ b/yardstick/benchmark/scenarios/networking/ping6.py
@@ -69,8 +69,8 @@ class Ping6(base.Scenario): # pragma: no cover
def _pre_setup(self):
for node_name in self.host_list:
self._ssh_host(node_name)
- self.client.run("cat > ~/pre_setup.sh",
- stdin=open(self.pre_setup_script, "rb"))
+ self.client._put_file_shell(
+ self.pre_setup_script, '~/pre_setup.sh')
status, stdout, stderr = self.client.execute(
"sudo bash pre_setup.sh")
@@ -117,20 +117,19 @@ class Ping6(base.Scenario): # pragma: no cover
if controller_node_name is None:
LOG.exception("Can't find controller node in the context!!!")
self._ssh_host(controller_node_name)
- self.client.run("cat > ~/metadata.txt",
- stdin=open(self.ping6_metadata_script, "rb"))
+ self.client._put_file_shell(
+ self.ping6_metadata_script, '~/metadata.txt')
# run script to setup ipv6 with nosdn or odl
sdn = self.options.get("sdn", 'nosdn')
if 'odl' in sdn:
- self.client.run("cat > ~/br-ex.radvd.conf",
- stdin=open(self.ping6_radvd_script, "rb"))
- self.client.run("cat > ~/setup_odl.sh",
- stdin=open(self.setup_odl_script, "rb"))
+ self.client._put_file_shell(
+ self.ping6_radvd_script, '~/br-ex.radvd.conf')
+ self.client._put_file_shell(
+ self.setup_odl_script, '~/setup_odl.sh')
setup_bash_file = "setup_odl.sh"
else:
- self.client.run("cat > ~/setup.sh",
- stdin=open(self.setup_script, "rb"))
+ self.client._put_file_shell(self.setup_script, '~/setup.sh')
setup_bash_file = "setup.sh"
cmd = "sudo bash %s %s %s" % \
(setup_bash_file, self.openrc, self.external_network)
@@ -156,8 +155,8 @@ class Ping6(base.Scenario): # pragma: no cover
self._ssh_host(self.host_list[0])
# find ipv4-int-network1 to ssh VM
- self.client.run("cat > ~/find_host.sh",
- stdin=open(self.ping6_find_host_script, "rb"))
+ self.client._put_file_shell(
+ self.ping6_find_host_script, '~/find_host.sh')
cmd = "sudo bash find_host.sh %s" % self.openrc
LOG.debug("Executing find_host command: %s", cmd)
status, stdout, stderr = self.client.execute(cmd)
@@ -171,8 +170,7 @@ class Ping6(base.Scenario): # pragma: no cover
stdin=open("/tmp/vRouterKey", "rb"))
# run ping6 benchmark
- self.client.run("cat > ~/ping6.sh",
- stdin=open(self.ping6_script, "rb"))
+ self.client._put_file_shell(self.ping6_script, '~/ping6.sh')
cmd = "sudo bash ping6.sh %s %s" % (self.openrc, self.ping_options)
LOG.debug("Executing ping6 command: %s", cmd)
status, stdout, stderr = self.client.execute(cmd)
@@ -208,8 +206,7 @@ class Ping6(base.Scenario): # pragma: no cover
self.teardown_script = pkg_resources.resource_filename(
'yardstick.benchmark.scenarios.networking',
Ping6.TEARDOWN_SCRIPT)
- self.client.run("cat > ~/teardown.sh",
- stdin=open(self.teardown_script, "rb"))
+ self.client._put_file_shell(self.teardown_script, '~/teardown.sh')
cmd = "sudo bash teardown.sh %s %s" % \
(self.openrc, self.external_network)
status, stdout, stderr = self.client.execute(cmd)
@@ -229,7 +226,7 @@ class Ping6(base.Scenario): # pragma: no cover
def _post_teardown(self):
for node_name in self.host_list:
self._ssh_host(node_name)
- self.client.run("cat > ~/post_teardown.sh",
- stdin=open(self.post_teardown_script, "rb"))
+ self.client._put_file_shell(
+ self.post_teardown_script, '~/post_teardown.sh')
status, stdout, stderr = self.client.execute(
"sudo bash post_teardown.sh")
diff --git a/yardstick/benchmark/scenarios/networking/pktgen.py b/yardstick/benchmark/scenarios/networking/pktgen.py
index 3e105767a..e2df706a2 100644
--- a/yardstick/benchmark/scenarios/networking/pktgen.py
+++ b/yardstick/benchmark/scenarios/networking/pktgen.py
@@ -71,8 +71,7 @@ class Pktgen(base.Scenario):
self.client.wait(timeout=600)
# copy script to host
- self.client.run("cat > ~/pktgen.sh",
- stdin=open(self.target_script, "rb"))
+ self.client._put_file_shell(self.target_script, '~/pktgen.sh')
self.setup_done = True
diff --git a/yardstick/benchmark/scenarios/networking/pktgen_dpdk.py b/yardstick/benchmark/scenarios/networking/pktgen_dpdk.py
index 189cc7895..503ea97e1 100644
--- a/yardstick/benchmark/scenarios/networking/pktgen_dpdk.py
+++ b/yardstick/benchmark/scenarios/networking/pktgen_dpdk.py
@@ -60,8 +60,7 @@ class PktgenDPDKLatency(base.Scenario):
self.server.wait(timeout=600)
# copy script to host
- self.server.run("cat > ~/testpmd_fwd.sh",
- stdin=open(self.testpmd_script, "rb"))
+ self.server._put_file_shell(self.testpmd_script, '~/testpmd_fwd.sh')
LOG.info("user:%s, host:%s", host_user, host_ip)
self.client = ssh.SSH(host_user, host_ip,
@@ -70,8 +69,8 @@ class PktgenDPDKLatency(base.Scenario):
self.client.wait(timeout=600)
# copy script to host
- self.client.run("cat > ~/pktgen_dpdk.sh",
- stdin=open(self.pktgen_dpdk_script, "rb"))
+ self.client._put_file_shell(
+ self.pktgen_dpdk_script, '~/pktgen_dpdk.sh')
self.setup_done = True
self.testpmd_args = ''
@@ -153,7 +152,7 @@ class PktgenDPDKLatency(base.Scenario):
latency_sum = 0
for i in latency_list:
latency_sum += int(i)
- avg_latency = latency_sum/len(latency_list)
+ avg_latency = latency_sum / len(latency_list)
result.update({"avg_latency": avg_latency})
diff --git a/yardstick/benchmark/scenarios/networking/sfc.py b/yardstick/benchmark/scenarios/networking/sfc.py
index 9494e70d2..1bd99b957 100644
--- a/yardstick/benchmark/scenarios/networking/sfc.py
+++ b/yardstick/benchmark/scenarios/networking/sfc.py
@@ -50,8 +50,7 @@ class Sfc(base.Scenario): # pragma: no cover
self.server = ssh.SSH(target_user, target_ip, password=target_pwd,
port=target_ssh_port)
self.server.wait(timeout=600)
- self.server.run("cat > ~/server.sh",
- stdin=open(self.server_script, "rb"))
+ self.server._put_file_shell(self.server_script, '~/server.sh')
cmd_server = "sudo bash server.sh"
LOG.debug("Executing command: %s", cmd_server)
status, stdout, stderr = self.server.execute(cmd_server)
diff --git a/yardstick/benchmark/scenarios/networking/vsperf.py b/yardstick/benchmark/scenarios/networking/vsperf.py
index 82db1e254..4f4ef21eb 100644
--- a/yardstick/benchmark/scenarios/networking/vsperf.py
+++ b/yardstick/benchmark/scenarios/networking/vsperf.py
@@ -32,14 +32,11 @@ class Vsperf(base.Scenario):
the valid values are "rfc2544", "continuous", "back2back"
type: string
default: "rfc2544"
- pkt_sizes - a packet size for which test should be executed;
- Multiple packet sizes can be tested by modification of Sequence runner
+ frame_size - a frame size for which test should be executed;
+ Multiple frame sizes can be tested by modification of sequence runner
section inside TC YAML definition.
type: string
default: "64"
- duration - sets duration for which traffic will be generated
- type: int
- default: 30
bidirectional - speficies if traffic will be uni (False) or bi-directional
(True)
type: string
@@ -47,9 +44,6 @@ class Vsperf(base.Scenario):
iload - specifies frame rate
type: string
default: 100
- rfc2544_trials - the number of trials performed for each packet size
- type: string
- default: NA
multistream - the number of simulated streams
type: string
default: 0 (disabled)
@@ -57,11 +51,24 @@ class Vsperf(base.Scenario):
the valid values are "L4", "L3" and "L2"
type: string
default: "L4"
- conf-file - path to the vsperf configuration file, which will be uploaded
- to the VM
+ test_params - specifies a string with a list of vsperf configuration
+ parameters, which will be passed to the '--test-params' CLI argument;
+ Parameters should be stated in the form of 'param=value' and separated
+ by a semicolon. Please check VSPERF documentation for details about
+ available configuration parameters and their data types.
+ In case that both 'test_params' and 'conf_file' are specified,
+ then values from 'test_params' will override values defined
+ in the configuration file.
+ type: string
+ default: NA
+ conf_file - path to the vsperf configuration file, which will be uploaded
+ to the VM;
+ In case that both 'test_params' and 'conf_file' are specified,
+ then values from 'test_params' will override values defined
+ in configuration file.
type: string
default: NA
- setup-script - path to the setup script, which will be executed during
+ setup_script - path to the setup script, which will be executed during
setup and teardown phases
type: string
default: NA
@@ -80,8 +87,6 @@ class Vsperf(base.Scenario):
"""
__scenario_type__ = "Vsperf"
- VSPERF_CONF = '~/vsperf-yardstick.conf'
-
def __init__(self, scenario_cfg, context_cfg):
self.scenario_cfg = scenario_cfg
self.context_cfg = context_cfg
@@ -93,13 +98,18 @@ class Vsperf(base.Scenario):
None)
self.br_ex = self.scenario_cfg['options'].get('external_bridge',
'br-ex')
- self.vsperf_conf = os.path.expanduser(
- self.scenario_cfg['options'].get('conf-file', Vsperf.VSPERF_CONF))
- self.setup_script = self.scenario_cfg['options'].get('setup-script',
+ self.vsperf_conf = self.scenario_cfg['options'].get('conf_file', None)
+ if self.vsperf_conf:
+ self.vsperf_conf = os.path.expanduser(self.vsperf_conf)
+
+ self.setup_script = self.scenario_cfg['options'].get('setup_script',
None)
if self.setup_script:
self.setup_script = os.path.expanduser(self.setup_script)
+ self.test_params = self.scenario_cfg['options'].get('test-params',
+ None)
+
def setup(self):
'''scenario setup'''
vsperf = self.context_cfg['host']
@@ -124,8 +134,7 @@ class Vsperf(base.Scenario):
self.client.wait(timeout=1800)
# copy script to host
- self.client.run("cat > ~/vsperf.conf",
- stdin=open(self.vsperf_conf, "rb"))
+ self.client._put_file_shell(self.vsperf_conf, '~/vsperf.conf')
# execute external setup script
if self.setup_script:
@@ -166,18 +175,26 @@ class Vsperf(base.Scenario):
options = self.scenario_cfg['options']
test_params = []
test_params.append(add_test_params(options, "traffic_type", "rfc2544"))
- test_params.append(add_test_params(options, "pkt_sizes", "64"))
- test_params.append(add_test_params(options, "duration", None))
test_params.append(add_test_params(options, "bidirectional", "False"))
test_params.append(add_test_params(options, "iload", 100))
- test_params.append(add_test_params(options, "rfc2544_trials", None))
test_params.append(add_test_params(options, "multistream", None))
test_params.append(add_test_params(options, "stream_type", None))
+ if 'frame_size' in options:
+ test_params.append("%s=(%s,)" % ('TRAFFICGEN_PKT_SIZES',
+ options['frame_size']))
+ if 'test_params' in options:
+ test_params.append(options['test_params'])
+
+ # filter empty parameters and escape quotes and double quotes
+ test_params = [tp.replace('"', '\\"').replace("'", "\\'")
+ for tp in test_params if tp]
# execute vsperf
cmd = "source ~/vsperfenv/bin/activate ; cd vswitchperf ; "
- cmd += "./vsperf --mode trafficgen --conf-file ~/vsperf.conf "
- cmd += "--test-params=\"%s\"" % (';'.join(filter(None, test_params)))
+ cmd += "./vsperf --mode trafficgen "
+ if self.vsperf_conf:
+ cmd += "--conf-file ~/vsperf.conf "
+ cmd += "--test-params=\"%s\"" % (';'.join(test_params))
LOG.debug("Executing command: %s", cmd)
status, stdout, stderr = self.client.execute(cmd)
diff --git a/yardstick/benchmark/scenarios/storage/fio.py b/yardstick/benchmark/scenarios/storage/fio.py
index 0e4153643..4e004235d 100644
--- a/yardstick/benchmark/scenarios/storage/fio.py
+++ b/yardstick/benchmark/scenarios/storage/fio.py
@@ -70,8 +70,7 @@ class Fio(base.Scenario):
self.client.wait(timeout=600)
# copy script to host
- self.client.run("cat > ~/fio.sh",
- stdin=open(self.target_script, "rb"))
+ self.client._put_file_shell(self.target_script, '~/fio.sh')
self.setup_done = True
diff --git a/yardstick/benchmark/scenarios/storage/storagecapacity.py b/yardstick/benchmark/scenarios/storage/storagecapacity.py
index bed45fa6d..bf5bc2810 100644
--- a/yardstick/benchmark/scenarios/storage/storagecapacity.py
+++ b/yardstick/benchmark/scenarios/storage/storagecapacity.py
@@ -64,8 +64,7 @@ class StorageCapacity(base.Scenario):
self.client.wait(timeout=600)
# copy script to host
- self.client.run("cat > ~/storagecapacity.sh",
- stdin=open(self.target_script, 'rb'))
+ self.client._put_file_shell(self.target_script, '~/storagecapacity.sh')
self.setup_done = True
@@ -109,7 +108,7 @@ class StorageCapacity(base.Scenario):
for i in range(len(device_name_arr)):
r[device_name_arr[i]] = {"min_util": min_util_arr[i],
"max_util": max_util_arr[i],
- "avg_util": avg_util_arr[i]/count}
+ "avg_util": avg_util_arr[i] / count}
return r
def run(self, result):
diff --git a/yardstick/benchmark/scenarios/storage/storperf.py b/yardstick/benchmark/scenarios/storage/storperf.py
index d39c23aa2..72ceff7ce 100644
--- a/yardstick/benchmark/scenarios/storage/storperf.py
+++ b/yardstick/benchmark/scenarios/storage/storperf.py
@@ -54,6 +54,7 @@ class StorPerf(base.Scenario):
def __init__(self, scenario_cfg, context_cfg):
"""Scenario construction."""
+ super(StorPerf, self).__init__()
self.scenario_cfg = scenario_cfg
self.context_cfg = context_cfg
self.options = self.scenario_cfg["options"]
@@ -75,8 +76,8 @@ class StorPerf(base.Scenario):
setup_query_content = json.loads(setup_query.content)
if setup_query_content["stack_created"]:
self.setup_done = True
- LOG.debug("stack_created: %s"
- % setup_query_content["stack_created"])
+ LOG.debug("stack_created: %s",
+ setup_query_content["stack_created"])
def setup(self):
"""Set the configuration."""
@@ -85,45 +86,44 @@ class StorPerf(base.Scenario):
"agent_image", "volume_size"]
for env_argument in env_args_payload_list:
- if env_argument in self.options:
+ try:
env_args[env_argument] = self.options[env_argument]
+ except KeyError:
+ pass
- LOG.info("Creating a stack on node %s with parameters %s" %
- (self.target, env_args))
+ LOG.info("Creating a stack on node %s with parameters %s",
+ self.target, env_args)
setup_res = requests.post('http://%s:5000/api/v1.0/configurations'
% self.target, json=env_args)
setup_res_content = json.loads(setup_res.content)
- if setup_res.status_code == 400:
+ if setup_res.status_code != 200:
raise RuntimeError("Failed to create a stack, error message:",
setup_res_content["message"])
elif setup_res.status_code == 200:
- LOG.info("stack_id: %s" % setup_res_content["stack_id"])
+ LOG.info("stack_id: %s", setup_res_content["stack_id"])
while not self.setup_done:
self._query_setup_state()
time.sleep(self.query_interval)
- # TODO: Support Storperf job status.
+ def _query_job_state(self, job_id):
+ """Query the status of the supplied job_id and report on metrics"""
+ LOG.info("Fetching report for %s...", job_id)
+ report_res = requests.get('http://{}:5000/api/v1.0/jobs'.format
+ (self.target), params={'id': job_id})
- # def _query_job_state(self, job_id):
- # """Query the status of the supplied job_id and report on metrics"""
- # LOG.info("Fetching report for %s..." % job_id)
- # report_res = requests.get('http://%s:5000/api/v1.0/jobs?id=%s' %
- # (self.target, job_id))
+ report_res_content = json.loads(report_res.content)
- # report_res_content = json.loads(report_res.content)
+ if report_res.status_code != 200:
+ raise RuntimeError("Failed to fetch report, error message:",
+ report_res_content["message"])
+ else:
+ job_status = report_res_content["status"]
- # if report_res.status_code == 400:
- # raise RuntimeError("Failed to fetch report, error message:",
- # report_res_content["message"])
- # else:
- # job_status = report_res_content["status"]
-
- # LOG.debug("Job is: %s..." % job_status)
- # if job_status == "completed":
- # self.job_completed = True
+ LOG.debug("Job is: %s...", job_status)
+ self.job_completed = job_status == "completed"
# TODO: Support using StorPerf ReST API to read Job ETA.
@@ -145,37 +145,36 @@ class StorPerf(base.Scenario):
"target", "nossd", "nowarm", "workload"]
for job_argument in job_args_payload_list:
- if job_argument in self.options:
+ try:
job_args[job_argument] = self.options[job_argument]
+ except KeyError:
+ pass
- LOG.info("Starting a job with parameters %s" % job_args)
+ LOG.info("Starting a job with parameters %s", job_args)
job_res = requests.post('http://%s:5000/api/v1.0/jobs' % self.target,
json=job_args)
job_res_content = json.loads(job_res.content)
- if job_res.status_code == 400:
+ if job_res.status_code != 200:
raise RuntimeError("Failed to start a job, error message:",
job_res_content["message"])
elif job_res.status_code == 200:
job_id = job_res_content["job_id"]
- LOG.info("Started job id: %s..." % job_id)
+ LOG.info("Started job id: %s...", job_id)
+
+ while not self.job_completed:
+ self._query_job_state(job_id)
+ time.sleep(self.query_interval)
- time.sleep(self.timeout)
terminate_res = requests.delete('http://%s:5000/api/v1.0/jobs' %
self.target)
- if terminate_res.status_code == 400:
+ if terminate_res.status_code != 200:
terminate_res_content = json.loads(terminate_res.content)
raise RuntimeError("Failed to start a job, error message:",
terminate_res_content["message"])
- # TODO: Support Storperf job status.
-
- # while not self.job_completed:
- # self._query_job_state(job_id)
- # time.sleep(self.query_interval)
-
# TODO: Support using ETA to polls for completion.
# Read ETA, next poll in 1/2 ETA time slot.
# If ETA is greater than the maximum allowed job time,
diff --git a/yardstick/cmd/cli.py b/yardstick/cmd/cli.py
index f2406bf08..beaa187aa 100644
--- a/yardstick/cmd/cli.py
+++ b/yardstick/cmd/cli.py
@@ -19,11 +19,13 @@ 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
from yardstick.cmd.commands import testcase
from yardstick.cmd.commands import plugin
+from yardstick.cmd.commands import env
CONF = cfg.CONF
cli_opts = [
@@ -62,10 +64,12 @@ class YardstickCLI():
'runner': runner.RunnerCommands,
'scenario': scenario.ScenarioCommands,
'testcase': testcase.TestcaseCommands,
- 'plugin': plugin.PluginCommands
+ 'plugin': plugin.PluginCommands,
+ 'env': env.EnvCommand
}
def __init__(self):
+ self.opts = []
self._version = 'yardstick version %s ' % \
get_distribution('yardstick').version
@@ -111,7 +115,12 @@ class YardstickCLI():
title="Command categories",
help="Available categories",
handler=parser)
- CONF.register_cli_opt(category_opt)
+ self._register_opt(category_opt)
+
+ def _register_opt(self, opt):
+
+ CONF.register_cli_opt(opt)
+ self.opts.append(opt)
def _load_cli_config(self, argv):
@@ -121,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):
@@ -137,28 +143,39 @@ class YardstickCLI():
func = CONF.category.func
func(CONF.category)
- def _dispath_func_task(self, task_id, timestamp):
+ def _dispath_func_task(self, task_id):
# dispatch to category parser
func = CONF.category.func
- func(CONF.category, task_id=task_id, timestamp=timestamp)
+ func(CONF.category, task_id=task_id)
+
+ def _clear_config_opts(self):
+
+ CONF.clear()
+ CONF.unregister_opts(self.opts)
def main(self, argv): # pragma: no cover
'''run the command line interface'''
- self._register_cli_opt()
+ try:
+ self._register_cli_opt()
- self._load_cli_config(argv)
+ self._load_cli_config(argv)
- self._handle_global_opts()
+ self._handle_global_opts()
- self._dispath_func_notask()
+ self._dispath_func_notask()
+ finally:
+ self._clear_config_opts()
- def api(self, argv, task_id, timestamp): # pragma: no cover
+ def api(self, argv, task_id): # pragma: no cover
'''run the api interface'''
- self._register_cli_opt()
+ try:
+ self._register_cli_opt()
- self._load_cli_config(argv)
+ self._load_cli_config(argv)
- self._handle_global_opts()
+ self._handle_global_opts()
- self._dispath_func_task(task_id, timestamp)
+ self._dispath_func_task(task_id)
+ finally:
+ self._clear_config_opts()
diff --git a/yardstick/cmd/commands/env.py b/yardstick/cmd/commands/env.py
new file mode 100644
index 000000000..098379ae1
--- /dev/null
+++ b/yardstick/cmd/commands/env.py
@@ -0,0 +1,39 @@
+##############################################################################
+# 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 logging
+
+from yardstick.common.httpClient import HttpClient
+from yardstick.common import constants
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+
+class EnvCommand(object):
+ '''
+
+ Set of commands to prepare environment
+ '''
+ def do_influxdb(self, args):
+ url = constants.YARDSTICK_ENV_ACTION_API
+ data = {'action': 'createInfluxDBContainer'}
+ HttpClient().post(url, data)
+ logger.debug('Now creating and configing influxdb')
+
+ def do_grafana(self, args):
+ url = constants.YARDSTICK_ENV_ACTION_API
+ data = {'action': 'createGrafanaContainer'}
+ HttpClient().post(url, data)
+ logger.debug('Now creating and configing grafana')
+
+ def do_prepare(self, args):
+ url = constants.YARDSTICK_ENV_ACTION_API
+ data = {'action': 'prepareYardstickEnv'}
+ HttpClient().post(url, data)
+ logger.debug('Now preparing environment')
diff --git a/yardstick/cmd/commands/task.py b/yardstick/cmd/commands/task.py
index a10a2a8a3..9524778ba 100644
--- a/yardstick/cmd/commands/task.py
+++ b/yardstick/cmd/commands/task.py
@@ -17,12 +17,15 @@ import ipaddress
import time
import logging
import uuid
+import errno
from itertools import ifilter
from yardstick.benchmark.contexts.base import Context
from yardstick.benchmark.runners import base as base_runner
from yardstick.common.task_template import TaskTemplate
from yardstick.common.utils import cliargs
+from yardstick.common.utils import source_env
+from yardstick.common import constants
output_file_default = "/tmp/yardstick.out"
test_cases_dir_default = "tests/opnfv/test_cases/"
@@ -56,6 +59,10 @@ class TaskCommands(object):
atexit.register(atexit_handler)
+ self.task_id = kwargs.get('task_id', str(uuid.uuid4()))
+
+ check_environment()
+
total_start_time = time.time()
parser = TaskParser(args.inputfile[0])
@@ -81,7 +88,7 @@ class TaskCommands(object):
one_task_start_time = time.time()
parser.path = task_files[i]
scenarios, run_in_parallel, meet_precondition = parser.parse_task(
- task_args[i], task_args_fnames[i])
+ self.task_id, task_args[i], task_args_fnames[i])
if not meet_precondition:
LOG.info("meet_precondition is %s, please check envrionment",
@@ -232,7 +239,7 @@ class TaskParser(object):
return valid_task_files, valid_task_args, valid_task_args_fnames
- def parse_task(self, task_args=None, task_args_file=None):
+ def parse_task(self, task_id, task_args=None, task_args_file=None):
'''parses the task file and return an context and scenario instances'''
print "Parsing task config:", self.path
@@ -291,7 +298,6 @@ class TaskParser(object):
run_in_parallel = cfg.get("run_in_parallel", False)
# add tc and task id for influxdb extended tags
- task_id = str(uuid.uuid4())
for scenario in cfg["scenarios"]:
task_name = os.path.splitext(os.path.basename(self.path))[0]
scenario["tc"] = task_name
@@ -482,3 +488,14 @@ def parse_task_args(src_name, args):
% {"src": src_name, "src_type": type(kw)})
raise TypeError()
return kw
+
+
+def check_environment():
+ auth_url = os.environ.get('OS_AUTH_URL', None)
+ if not auth_url:
+ try:
+ source_env(constants.OPENSTACK_RC_FILE)
+ except IOError as e:
+ if e.errno != errno.EEXIST:
+ raise
+ LOG.debug('OPENRC file not found')
diff --git a/yardstick/common/constants.py b/yardstick/common/constants.py
index 40b29a717..705e1ad87 100644
--- a/yardstick/common/constants.py
+++ b/yardstick/common/constants.py
@@ -1,3 +1,54 @@
-CONFIG_SAMPLE = '/etc/yardstick/config.yaml'
+##############################################################################
+# 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
-RELENG_DIR = 'releng.dir'
+DOCKER_URL = 'unix://var/run/docker.sock'
+
+# database config
+USER = 'root'
+PASSWORD = 'root'
+DATABASE = 'yardstick'
+
+INFLUXDB_IMAGE = 'tutum/influxdb'
+INFLUXDB_TAG = '0.13'
+
+GRAFANA_IMAGE = 'grafana/grafana'
+GRAFANA_TAGS = '3.1.1'
+
+dirname = os.path.dirname
+abspath = os.path.abspath
+join = os.path.join
+sep = os.path.sep
+
+INSTALLERS = ['apex', 'compass', 'fuel', 'joid']
+
+YARDSTICK_ROOT_PATH = dirname(dirname(dirname(abspath(__file__)))) + sep
+
+YARDSTICK_REPOS_DIR = '/home/opnfv/repos/yardstick'
+
+YARDSTICK_CONFIG_DIR = '/etc/yardstick/'
+
+YARDSTICK_CONFIG_FILE = join(YARDSTICK_CONFIG_DIR, 'yardstick.conf')
+
+YARDSTICK_CONFIG_SAMPLE_DIR = join(YARDSTICK_ROOT_PATH, 'etc/yardstick/')
+
+YARDSTICK_CONFIG_SAMPLE_FILE = join(YARDSTICK_CONFIG_SAMPLE_DIR,
+ 'yardstick.conf.sample')
+
+RELENG_DIR = '/home/opnfv/repos/releng'
+
+OS_FETCH_SCRIPT = 'utils/fetch_os_creds.sh'
+
+CLEAN_IMAGES_SCRIPT = 'tests/ci/clean_images.sh'
+
+LOAD_IMAGES_SCRIPT = 'tests/ci/load_images.sh'
+
+OPENSTACK_RC_FILE = join(YARDSTICK_CONFIG_DIR, 'openstack.creds')
+
+YARDSTICK_ENV_ACTION_API = 'http://localhost:5000/yardstick/env/action'
diff --git a/yardstick/common/httpClient.py b/yardstick/common/httpClient.py
new file mode 100644
index 000000000..ab2e9a379
--- /dev/null
+++ b/yardstick/common/httpClient.py
@@ -0,0 +1,30 @@
+##############################################################################
+# 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 json
+import logging
+
+import requests
+
+logger = logging.getLogger(__name__)
+
+
+class HttpClient(object):
+
+ def post(self, url, data):
+ data = json.dumps(data)
+ headers = {'Content-Type': 'application/json'}
+ try:
+ response = requests.post(url, data=data, headers=headers)
+ result = response.json()
+ logger.debug('The result is: %s', result)
+
+ return result
+ except Exception as e:
+ logger.debug('Failed: %s', e)
+ raise
diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py
new file mode 100644
index 000000000..25dcffadd
--- /dev/null
+++ b/yardstick/common/openstack_utils.py
@@ -0,0 +1,97 @@
+##############################################################################
+# 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
+# yardstick: this file is copied from rally and slightly modified
+##############################################################################
+
+import os
+import logging
+
+from keystoneauth1 import loading
+from keystoneauth1 import session
+
+log = logging.getLogger(__name__)
+
+DEFAULT_HEAT_API_VERSION = '1'
+
+
+def get_credentials():
+ """Returns a creds dictionary filled with parsed from env"""
+ creds = {}
+
+ keystone_api_version = os.getenv('OS_IDENTITY_API_VERSION')
+
+ if keystone_api_version is None or keystone_api_version == '2':
+ keystone_v3 = False
+ tenant_env = 'OS_TENANT_NAME'
+ tenant = 'tenant_name'
+ else:
+ keystone_v3 = True
+ tenant_env = 'OS_PROJECT_NAME'
+ tenant = 'project_name'
+
+ # The most common way to pass these info to the script is to do it
+ # through environment variables.
+ creds.update({
+ "username": os.environ.get("OS_USERNAME"),
+ "password": os.environ.get("OS_PASSWORD"),
+ "auth_url": os.environ.get("OS_AUTH_URL"),
+ tenant: os.environ.get(tenant_env)
+ })
+
+ if keystone_v3:
+ if os.getenv('OS_USER_DOMAIN_NAME') is not None:
+ creds.update({
+ "user_domain_name": os.getenv('OS_USER_DOMAIN_NAME')
+ })
+ if os.getenv('OS_PROJECT_DOMAIN_NAME') is not None:
+ creds.update({
+ "project_domain_name": os.getenv('OS_PROJECT_DOMAIN_NAME')
+ })
+
+ cacert = os.environ.get("OS_CACERT")
+
+ if cacert is not None:
+ # each openstack client uses differnt kwargs for this
+ creds.update({"cacert": cacert,
+ "ca_cert": cacert,
+ "https_ca_cert": cacert,
+ "https_cacert": cacert,
+ "ca_file": cacert})
+ creds.update({"insecure": "True", "https_insecure": "True"})
+ if not os.path.isfile(cacert):
+ log.info("WARNING: The 'OS_CACERT' environment variable is set\
+ to %s but the file does not exist." % cacert)
+
+ return creds
+
+
+def get_session_auth():
+ loader = loading.get_plugin_loader('password')
+ creds = get_credentials()
+ auth = loader.load_from_options(**creds)
+ return auth
+
+
+def get_session():
+ auth = get_session_auth()
+ return session.Session(auth=auth)
+
+
+def get_endpoint(service_type, endpoint_type='publicURL'):
+ auth = get_session_auth()
+ return get_session().get_endpoint(auth=auth,
+ service_type=service_type,
+ endpoint_type=endpoint_type)
+
+
+def get_heat_api_version():
+ api_version = os.getenv('HEAT_API_VERSION')
+ if api_version is not None:
+ log.info("HEAT_API_VERSION is set in env as '%s'", api_version)
+ return api_version
+ return DEFAULT_HEAT_API_VERSION
diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py
index d639fb66a..3ecb0ae20 100644
--- a/yardstick/common/utils.py
+++ b/yardstick/common/utils.py
@@ -18,10 +18,20 @@
import os
import sys
import yaml
+import errno
+import subprocess
+import logging
+
from oslo_utils import importutils
+from keystoneauth1 import identity
+from keystoneauth1 import session
+from neutronclient.v2_0 import client
import yardstick
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
# Decorator for cli-args
def cliargs(*args, **kwargs):
@@ -91,3 +101,43 @@ def get_para_from_yaml(file_path, args):
else:
print 'file not exist'
return None
+
+
+def makedirs(d):
+ try:
+ os.makedirs(d)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+
+
+def execute_command(cmd):
+ exec_msg = "Executing command: '%s'" % cmd
+ logger.debug(exec_msg)
+
+ output = subprocess.check_output(cmd.split()).split(os.linesep)
+
+ return output
+
+
+def source_env(env_file):
+ p = subprocess.Popen(". %s; env" % env_file, stdout=subprocess.PIPE,
+ shell=True)
+ output = p.communicate()[0]
+ env = dict((line.split('=', 1) for line in output.splitlines()))
+ os.environ.update(env)
+ return env
+
+
+def get_openstack_session():
+ auth = identity.Password(auth_url=os.environ.get('OS_AUTH_URL'),
+ username=os.environ.get('OS_USERNAME'),
+ password=os.environ.get('OS_PASSWORD'),
+ tenant_name=os.environ.get('OS_TENANT_NAME'))
+ return session.Session(auth=auth)
+
+
+def get_neutron_client():
+ sess = get_openstack_session()
+ neutron_client = client.Client(session=sess)
+ return neutron_client
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/dispatcher/http.py b/yardstick/dispatcher/http.py
index 2298d00cc..98e772dd8 100644
--- a/yardstick/dispatcher/http.py
+++ b/yardstick/dispatcher/http.py
@@ -81,14 +81,14 @@ class HttpDispatcher(DispatchBase):
case_name = v["scenario_cfg"]["tc"]
break
if case_name == "":
- LOG.error('Test result : %s' % json.dumps(self.result))
+ LOG.error('Test result : %s', json.dumps(self.result))
LOG.error('The case_name cannot be found, no data will be posted.')
return
self.result["case_name"] = case_name
try:
- LOG.debug('Test result : %s' % json.dumps(self.result))
+ LOG.debug('Test result : %s', json.dumps(self.result))
res = requests.post(self.target,
data=json.dumps(self.result),
headers=self.headers,
diff --git a/yardstick/dispatcher/influxdb.py b/yardstick/dispatcher/influxdb.py
index 8673253b4..fc9f3e932 100644
--- a/yardstick/dispatcher/influxdb.py
+++ b/yardstick/dispatcher/influxdb.py
@@ -127,7 +127,7 @@ class InfluxdbDispatcher(DispatchBase):
return make_lines(msg).encode('utf-8')
def record_result_data(self, data):
- LOG.debug('Test result : %s' % json.dumps(data))
+ LOG.debug('Test result : %s', json.dumps(data))
self.raw_result.append(data)
if self.target == '':
# if the target was not set, do not do anything
@@ -148,13 +148,13 @@ class InfluxdbDispatcher(DispatchBase):
return 0
if self.tc == "":
- LOG.error('Test result : %s' % json.dumps(data))
+ LOG.error('Test result : %s', json.dumps(data))
LOG.error('The case_name cannot be found, no data will be posted.')
return -1
try:
line = self._data_to_line_protocol(data)
- LOG.debug('Test result line format : %s' % line)
+ LOG.debug('Test result line format : %s', line)
res = requests.post(self.influxdb_url,
data=line,
auth=(self.username, self.password),
@@ -171,5 +171,5 @@ class InfluxdbDispatcher(DispatchBase):
return 0
def flush_result_data(self):
- LOG.debug('Test result all : %s' % json.dumps(self.raw_result))
+ LOG.debug('Test result all : %s', json.dumps(self.raw_result))
return 0
diff --git a/yardstick/orchestrator/heat.py b/yardstick/orchestrator/heat.py
index f3a191503..4839455e1 100644
--- a/yardstick/orchestrator/heat.py
+++ b/yardstick/orchestrator/heat.py
@@ -7,10 +7,8 @@
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-""" Heat template and stack management
-"""
+"""Heat template and stack management"""
-import os
import time
import datetime
import getpass
@@ -18,10 +16,11 @@ import socket
import logging
import pkg_resources
import json
-import heatclient.client
-import keystoneclient
+
+import heatclient
from yardstick.common import template_format
+import yardstick.common.openstack_utils as op_utils
log = logging.getLogger(__name__)
@@ -30,32 +29,18 @@ log = logging.getLogger(__name__)
class HeatObject(object):
''' base class for template and stack'''
def __init__(self):
- self._keystone_client = None
self._heat_client = None
self.uuid = None
- def _get_keystone_client(self):
- '''returns a keystone client instance'''
-
- if self._keystone_client is None:
- self._keystone_client = keystoneclient.v2_0.client.Client(
- auth_url=os.environ.get('OS_AUTH_URL'),
- username=os.environ.get('OS_USERNAME'),
- password=os.environ.get('OS_PASSWORD'),
- tenant_name=os.environ.get('OS_TENANT_NAME'),
- cacert=os.environ.get('OS_CACERT'))
-
- return self._keystone_client
-
def _get_heat_client(self):
'''returns a heat client instance'''
if self._heat_client is None:
- keystone = self._get_keystone_client()
- heat_endpoint = keystone.service_catalog.url_for(
- service_type='orchestration')
+ sess = op_utils.get_session()
+ heat_endpoint = op_utils.get_endpoint(service_type='orchestration')
self._heat_client = heatclient.client.Client(
- '1', endpoint=heat_endpoint, token=keystone.auth_token)
+ op_utils.get_heat_api_version(),
+ endpoint=heat_endpoint, session=sess)
return self._heat_client
diff --git a/yardstick/ssh.py b/yardstick/ssh.py
index 8b71fe606..927ca94db 100644
--- a/yardstick/ssh.py
+++ b/yardstick/ssh.py
@@ -29,24 +29,29 @@ Execute command and get output:
Execute command with huge output:
- class PseudoFile(object):
+ class PseudoFile(io.RawIOBase):
def write(chunk):
if "error" in chunk:
email_admin(chunk)
- ssh = sshclient.SSH("root", "example.com")
- ssh.run("tail -f /var/log/syslog", stdout=PseudoFile(), timeout=False)
+ ssh = SSH("root", "example.com")
+ with PseudoFile() as p:
+ ssh.run("tail -f /var/log/syslog", stdout=p, timeout=False)
Execute local script on remote side:
ssh = sshclient.SSH("user", "example.com")
- status, out, err = ssh.execute("/bin/sh -s arg1 arg2",
- stdin=open("~/myscript.sh", "r"))
+
+ with open("~/myscript.sh", "r") as stdin_file:
+ status, out, err = ssh.execute('/bin/sh -s "arg1" "arg2"',
+ stdin=stdin_file)
Upload file:
- ssh = sshclient.SSH("user", "example.com")
- ssh.run("cat > ~/upload/file.gz", stdin=open("/store/file.gz", "rb"))
+ ssh = SSH("user", "example.com")
+ # use rb for binary files
+ with open("/store/file.gz", "rb") as stdin_file:
+ ssh.run("cat > ~/upload/file.gz", stdin=stdin_file)
Eventlet:
@@ -54,20 +59,20 @@ Eventlet:
or
eventlet.monkey_patch()
or
- sshclient = eventlet.import_patched("opentstack.common.sshclient")
+ sshclient = eventlet.import_patched("yardstick.ssh")
"""
-
+import os
import select
import socket
import time
+import re
+import logging
import paramiko
from scp import SCPClient
import six
-import logging
-LOG = logging.getLogger(__name__)
DEFAULT_PORT = 22
@@ -84,7 +89,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 +99,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 +113,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):
@@ -140,10 +157,12 @@ class SSH(object):
self._client = False
def run(self, cmd, stdin=None, stdout=None, stderr=None,
- raise_on_error=True, timeout=3600):
+ raise_on_error=True, timeout=3600,
+ keep_stdin_open=False, pty=False):
"""Execute specified command on the server.
:param cmd: Command to be executed.
+ :type cmd: str
:param stdin: Open file or string to pass to stdin.
:param stdout: Open file to connect to stdout.
:param stderr: Open file to connect to stderr.
@@ -151,6 +170,12 @@ class SSH(object):
then exception will be raized if non-zero code.
:param timeout: Timeout in seconds for command execution.
Default 1 hour. No timeout if set to 0.
+ :param keep_stdin_open: don't close stdin on empty reads
+ :type keep_stdin_open: bool
+ :param pty: Request a pseudo terminal for this connection.
+ This allows passing control characters.
+ Default False.
+ :type pty: bool
"""
client = self._get_client()
@@ -160,13 +185,17 @@ class SSH(object):
return self._run(client, cmd, stdin=stdin, stdout=stdout,
stderr=stderr, raise_on_error=raise_on_error,
- timeout=timeout)
+ timeout=timeout,
+ keep_stdin_open=keep_stdin_open, pty=pty)
def _run(self, client, cmd, stdin=None, stdout=None, stderr=None,
- raise_on_error=True, timeout=3600):
+ raise_on_error=True, timeout=3600,
+ keep_stdin_open=False, pty=False):
transport = client.get_transport()
session = transport.open_session()
+ if pty:
+ session.get_pty()
session.exec_command(cmd)
start_time = time.time()
@@ -186,14 +215,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
@@ -203,13 +232,15 @@ class SSH(object):
if not data_to_send:
data_to_send = stdin.read(4096)
if not data_to_send:
- stdin.close()
- session.shutdown_write()
- writes = []
- continue
- sent_bytes = session.send(data_to_send)
- # LOG.debug("sent: %s" % data_to_send[:sent_bytes])
- data_to_send = data_to_send[sent_bytes:]
+ # we may need to keep stdin open
+ if not keep_stdin_open:
+ stdin.close()
+ session.shutdown_write()
+ writes = []
+ if data_to_send:
+ sent_bytes = session.send(data_to_send)
+ # LOG.debug("sent: %s" % data_to_send[:sent_bytes])
+ data_to_send = data_to_send[sent_bytes:]
if session.exit_status_ready():
break
@@ -222,7 +253,7 @@ class SSH(object):
raise SSHError("Socket error.")
exit_status = session.recv_exit_status()
- if 0 != exit_status and raise_on_error:
+ if exit_status != 0 and raise_on_error:
fmt = "Command '%(cmd)s' failed with exit_status %(status)d."
details = fmt % {"cmd": cmd, "status": exit_status}
if stderr_data:
@@ -256,10 +287,10 @@ 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)
+ raise SSHTimeout("Timeout waiting for '%s'", self.host)
def put(self, files, remote_path=b'.', recursive=False):
client = self._get_client()
@@ -271,3 +302,40 @@ class SSH(object):
def send_command(self, command):
client = self._get_client()
client.exec_command(command, get_pty=True)
+
+ def _put_file_sftp(self, localpath, remotepath, mode=None):
+ client = self._get_client()
+
+ with client.open_sftp() as sftp:
+ sftp.put(localpath, remotepath)
+ if mode is None:
+ mode = 0o777 & os.stat(localpath).st_mode
+ sftp.chmod(remotepath, mode)
+
+ TILDE_EXPANSIONS_RE = re.compile("(^~[^/]*/)?(.*)")
+
+ def _put_file_shell(self, localpath, remotepath, mode=None):
+ # quote to stop wordpslit
+ tilde, remotepath = self.TILDE_EXPANSIONS_RE.match(remotepath).groups()
+ if not tilde:
+ tilde = ''
+ cmd = ['cat > %s"%s"' % (tilde, remotepath)]
+ if mode is not None:
+ # use -- so no options
+ cmd.append('chmod -- 0%o %s"%s"' % (mode, tilde, remotepath))
+
+ with open(localpath, "rb") as localfile:
+ # only chmod on successful cat
+ self.run("&& ".join(cmd), stdin=localfile)
+
+ def put_file(self, localpath, remotepath, mode=None):
+ """Copy specified local file to the server.
+
+ :param localpath: Local filename.
+ :param remotepath: Remote filename.
+ :param mode: Permissions to set after upload
+ """
+ try:
+ self._put_file_sftp(localpath, remotepath, mode=mode)
+ except (paramiko.SSHException, socket.error):
+ self._put_file_shell(localpath, remotepath, mode=mode)