diff options
49 files changed, 776 insertions, 243 deletions
diff --git a/api/actions/env.py b/api/actions/env.py index 321649940..fa0f95d90 100644 --- a/api/actions/env.py +++ b/api/actions/env.py @@ -8,49 +8,133 @@ ############################################################################## import logging import threading +import subprocess import time +import json +import os +import errno 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 common as common_utils 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: - container = _create_influxdb_container() _config_output_file() - thread = threading.Thread(target=_config_influxdb) - thread.start() - return common_utils.result_handler('success', container) + + 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: - message = 'Failed to create influxdb container: %s' % e - return common_utils.error_handler(message) + logger.debug('Error: %s', e) -def _create_influxdb_container(): - client = Client(base_url=config.DOCKER_URL) +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='tutum/influxdb', + 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) - return container def _config_influxdb(): - time.sleep(20) try: client = influx.get_data_db_client() client.create_user(config.USER, config.PASSWORD, config.DATABASE) @@ -61,11 +145,11 @@ def _config_influxdb(): def _config_output_file(): - yardstick_utils.makedirs('/etc/yardstick') - with open('/etc/yardstick/yardstick.conf', 'w') as f: + yardstick_utils.makedirs(config.YARDSTICK_CONFIG_DIR) + with open(config.YARDSTICK_CONFIG_FILE, 'w') as f: f.write("""\ [DEFAULT] -debug = True +debug = False dispatcher = influxdb [dispatcher_file] @@ -83,3 +167,93 @@ username = root password = root """ % api_conf.GATEWAY_IP) + + +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) + + _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 _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/actions/result.py b/api/actions/result.py index 10112ac68..1f200fbcc 100644 --- a/api/actions/result.py +++ b/api/actions/result.py @@ -30,8 +30,6 @@ def getResult(args): message = 'measurement and task_id must be provided' return common_utils.error_handler(message) - measurement = conf.TEST_CASE_PRE + measurement - 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)) @@ -40,8 +38,12 @@ def getResult(args): return common_utils.result_handler(0, []) def _finished(): - query_sql = query_template % (measurement, task_id) + 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) diff --git a/api/api-prepare.sh b/api/api-prepare.sh index c05dbb5ff..fade8ccc6 100755 --- a/api/api-prepare.sh +++ b/api/api-prepare.sh @@ -24,14 +24,26 @@ server { } } EOF +echo "daemon off;" >> /etc/nginx/nginx.conf fi # nginx service start when boot -cat << EOF >> /root/.bashrc +supervisor_config='/etc/supervisor/conf.d/yardstick.conf' -nginx_status=\$(service nginx status | grep not) -if [ -n "\${nginx_status}" ];then - service nginx restart - uwsgi -i /home/opnfv/repos/yardstick/api/yardstick.ini -fi +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 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 048804dc5..23afef74e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -48,8 +48,9 @@ RUN apt-get update && apt-get install -y \ 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 @@ -73,3 +74,4 @@ ADD http://download.cirros-cloud.net/0.3.3/cirros-0.3.3-x86_64-disk.img /home/op 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/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/install.sh b/install.sh index afb735195..e9b6035d9 100755 --- a/install.sh +++ b/install.sh @@ -16,6 +16,7 @@ apt-get update && apt-get install -y \ nginx \ uwsgi \ uwsgi-plugin-python \ + supervisor \ python-setuptools && \ easy_install -U setuptools diff --git a/requirements.txt b/requirements.txt index e391c9210..6b4edf3f0 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 @@ -28,7 +28,8 @@ setup( 'yardstick/nodes/*/*.yaml' ], 'tests': [ - 'opnfv/*/*.yaml' + 'opnfv/*/*.yaml', + 'ci/*.sh' ] }, url="https://www.opnfv.org", diff --git a/tests/ci/yardstick-verify b/tests/ci/yardstick-verify index 1a6682f85..7644c96c4 100755 --- a/tests/ci/yardstick-verify +++ b/tests/ci/yardstick-verify @@ -162,7 +162,7 @@ run_test() cat << EOF > /etc/yardstick/yardstick.conf [DEFAULT] -debug = True +debug = False dispatcher = ${DISPATCHER_TYPE} [dispatcher_file] 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/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 1e021a051..88638a0a8 100644 --- a/tests/unit/test_ssh.py +++ b/tests/unit/test_ssh.py @@ -17,6 +17,7 @@ # rally/tests/unit/common/test_sshutils.py import os +import socket import unittest from cStringIO import StringIO @@ -164,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): @@ -307,6 +308,61 @@ 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): + self.test_client.run = mock.Mock() + self.test_client._put_file_shell("localfile", "remotefile", 0o42) + + self.test_client.run.assert_called_once_with( + 'cat > "remotefile"&& chmod -- 042 "remotefile"', + 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-modify b/tools/yardstick-img-modify index c28e2ad59..0033383ef 100755 --- a/tools/yardstick-img-modify +++ b/tools/yardstick-img-modify @@ -153,7 +153,7 @@ cleanup() { mount | grep $mountdir && umount $mountdir mount | grep "/mnt/vivid" && umount "/mnt/vivid" if [ -f $raw_imgfile ]; then - kpartx -dv $raw_imgfile || true + kpartx -dv $raw_imgfile fi rm -f $raw_imgfile rm -rf $mountdir diff --git a/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py b/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py index 3b1f8ef76..e88fed636 100644 --- a/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py +++ b/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py @@ -61,9 +61,10 @@ 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) @@ -98,10 +99,11 @@ class BaremetalAttacker(BaseAttacker): 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 a452c37ac..595067a95 100644 --- a/yardstick/benchmark/scenarios/availability/attacker/attacker_general.py +++ b/yardstick/benchmark/scenarios/availability/attacker/attacker_general.py @@ -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: @@ -85,10 +87,12 @@ class GeneralAttacker(BaseAttacker): 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 2ccc231da..1d190a160 100644 --- a/yardstick/benchmark/scenarios/availability/attacker/attacker_process.py +++ b/yardstick/benchmark/scenarios/availability/attacker/attacker_process.py @@ -45,9 +45,10 @@ 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!") @@ -59,11 +60,13 @@ class ProcessAttacker(BaseAttacker): 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/monitor/monitor_command.py b/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py index 366d16e73..cd33e6188 100644 --- a/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py +++ b/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py @@ -58,9 +58,10 @@ 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) diff --git a/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py b/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py index 359cde671..461a2ded5 100644 --- a/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py +++ b/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py @@ -48,13 +48,15 @@ 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 diff --git a/yardstick/benchmark/scenarios/availability/monitor/monitor_process.py b/yardstick/benchmark/scenarios/availability/monitor/monitor_process.py index a88b8d42e..5f492ad69 100644 --- a/yardstick/benchmark/scenarios/availability/monitor/monitor_process.py +++ b/yardstick/benchmark/scenarios/availability/monitor/monitor_process.py @@ -35,9 +35,10 @@ 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) return False diff --git a/yardstick/benchmark/scenarios/availability/operation/operation_general.py b/yardstick/benchmark/scenarios/availability/operation/operation_general.py index b3a20c344..c82df836d 100644 --- a/yardstick/benchmark/scenarios/availability/operation/operation_general.py +++ b/yardstick/benchmark/scenarios/availability/operation/operation_general.py @@ -55,13 +55,15 @@ 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)) @@ -72,10 +74,12 @@ class GeneralOperaion(BaseOperation): 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/result_checker_general.py b/yardstick/benchmark/scenarios/availability/result_checker/result_checker_general.py index 8c9d16026..275aff076 100644 --- a/yardstick/benchmark/scenarios/availability/result_checker/result_checker_general.py +++ b/yardstick/benchmark/scenarios/availability/result_checker/result_checker_general.py @@ -53,17 +53,19 @@ 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)) diff --git a/yardstick/benchmark/scenarios/compute/cachestat.py b/yardstick/benchmark/scenarios/compute/cachestat.py index 25300dd46..20786ff61 100644 --- a/yardstick/benchmark/scenarios/compute/cachestat.py +++ b/yardstick/benchmark/scenarios/compute/cachestat.py @@ -85,8 +85,7 @@ 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 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/cyclictest.py b/yardstick/benchmark/scenarios/compute/cyclictest.py index a6c4d95cf..568e6e7df 100644 --- a/yardstick/benchmark/scenarios/compute/cyclictest.py +++ b/yardstick/benchmark/scenarios/compute/cyclictest.py @@ -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/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/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 39912a95a..4f4ef21eb 100644 --- a/yardstick/benchmark/scenarios/networking/vsperf.py +++ b/yardstick/benchmark/scenarios/networking/vsperf.py @@ -133,10 +133,8 @@ class Vsperf(base.Scenario): # traffic generation could last long self.client.wait(timeout=1800) - # copy script to host if needed - if self.vsperf_conf: - self.client.run("cat > ~/vsperf.conf", - stdin=open(self.vsperf_conf, "rb")) + # copy script to host + self.client._put_file_shell(self.vsperf_conf, '~/vsperf.conf') # execute external setup script if self.setup_script: 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 06c329d4d..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"] @@ -85,8 +86,10 @@ 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) @@ -95,7 +98,7 @@ class StorPerf(base.Scenario): 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: @@ -105,25 +108,22 @@ class StorPerf(base.Scenario): 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,8 +145,10 @@ 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) job_res = requests.post('http://%s:5000/api/v1.0/jobs' % self.target, @@ -154,28 +156,25 @@ class StorPerf(base.Scenario): 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) - time.sleep(self.timeout) + while not self.job_completed: + self._query_job_state(job_id) + time.sleep(self.query_interval) + 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 cac3dc5bf..beaa187aa 100644 --- a/yardstick/cmd/cli.py +++ b/yardstick/cmd/cli.py @@ -156,24 +156,26 @@ class YardstickCLI(): 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._clear_config_opts() + self._dispath_func_notask() + finally: + self._clear_config_opts() def api(self, argv, task_id): # pragma: no cover '''run the api interface''' - self._register_cli_opt() - - self._load_cli_config(argv) + try: + self._register_cli_opt() - self._handle_global_opts() + self._load_cli_config(argv) - self._dispath_func_task(task_id) + self._handle_global_opts() - self._clear_config_opts() + 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 index d9c0c0a3f..098379ae1 100644 --- a/yardstick/cmd/commands/env.py +++ b/yardstick/cmd/commands/env.py @@ -6,12 +6,34 @@ # 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 = 'http://localhost:5000/yardstick/env/action' + 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 47fb2ee60..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/" @@ -58,6 +61,8 @@ class TaskCommands(object): self.task_id = kwargs.get('task_id', str(uuid.uuid4())) + check_environment() + total_start_time = time.time() parser = TaskParser(args.inputfile[0]) @@ -483,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 8fbc82f0e..443b3e810 100644 --- a/yardstick/common/constants.py +++ b/yardstick/common/constants.py @@ -1,6 +1,4 @@ -CONFIG_SAMPLE = '/etc/yardstick/config.yaml' - -RELENG_DIR = 'releng.dir' +import os DOCKER_URL = 'unix://var/run/docker.sock' @@ -8,3 +6,33 @@ DOCKER_URL = 'unix://var/run/docker.sock' 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 +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 = os.path.join(YARDSTICK_CONFIG_DIR, 'yardstick.conf') + +RELENG_DIR = '/home/opnfv/repos/releng' + +OS_FETCH_SCRIPT = 'utils/fetch_os_creds.sh' + +LOAD_IMAGES_SCRIPT = 'tests/ci/load_images.sh' + +OPENSTACK_RC_FILE = os.path.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 index b6959b400..ab2e9a379 100644 --- a/yardstick/common/httpClient.py +++ b/yardstick/common/httpClient.py @@ -23,5 +23,8 @@ class HttpClient(object): 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 afbe4e8ec..3ecb0ae20 100644 --- a/yardstick/common/utils.py +++ b/yardstick/common/utils.py @@ -19,10 +19,19 @@ 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): @@ -100,3 +109,35 @@ def 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/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 8485dccd0..2ba6de92e 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,7 +59,7 @@ Eventlet: or eventlet.monkey_patch() or - sshclient = eventlet.import_patched("opentstack.common.sshclient") + sshclient = eventlet.import_patched("yardstick.ssh") """ import os @@ -152,7 +157,7 @@ class SSH(object): def run(self, cmd, stdin=None, stdout=None, stderr=None, raise_on_error=True, timeout=3600, - keep_stdin_open=False): + keep_stdin_open=False, pty=False): """Execute specified command on the server. :param cmd: Command to be executed. @@ -166,6 +171,10 @@ class SSH(object): 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() @@ -176,14 +185,16 @@ class SSH(object): return self._run(client, cmd, stdin=stdin, stdout=stdout, stderr=stderr, raise_on_error=raise_on_error, timeout=timeout, - keep_stdin_open=keep_stdin_open) + 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, - keep_stdin_open=False): + 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() @@ -290,3 +301,37 @@ 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) + + def _put_file_shell(self, localpath, remotepath, mode=None): + # quote to stop wordpslit + cmd = ['cat > "%s"' % remotepath] + if mode is not None: + # use -- so no options + cmd.append('chmod -- 0%o "%s"' % (mode, remotepath)) + + with open(localpath, "rb") as localfile: + # only chmod on successful cat + cmd = "&& ".join(cmd) + self.run(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 + """ + import socket + try: + self._put_file_sftp(localpath, remotepath, mode=mode) + except (paramiko.SSHException, socket.error): + self._put_file_shell(localpath, remotepath, mode=mode) |