diff options
85 files changed, 1037 insertions, 304 deletions
diff --git a/api/conf.py b/api/conf.py index abaf34a1f..a4f332533 100644 --- a/api/conf.py +++ b/api/conf.py @@ -15,8 +15,6 @@ 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/' diff --git a/api/database/__init__.py b/api/database/__init__.py index d7cf4f9c4..753b34684 100644 --- a/api/database/__init__.py +++ b/api/database/__init__.py @@ -13,10 +13,12 @@ from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.ext.declarative import declarative_base +from yardstick.common import constants as consts + logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) -engine = create_engine('sqlite:////tmp/yardstick.db', convert_unicode=True) +engine = create_engine(consts.SQLITE, convert_unicode=True) db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) diff --git a/api/server.py b/api/server.py index 5bac1ba47..be7963481 100644 --- a/api/server.py +++ b/api/server.py @@ -52,7 +52,6 @@ def init_db(): Base.metadata.create_all(bind=engine) -init_db() reduce(lambda a, b: a.add_resource(b.resource, b.url, endpoint=b.endpoint) or a, urlpatterns, api) @@ -60,4 +59,5 @@ if __name__ == '__main__': _init_logging() logger.setLevel(logging.DEBUG) logger.info('Starting server') + init_db() app.run(host='0.0.0.0') diff --git a/requirements.txt b/requirements.txt index 7041a96e7..107e8dee4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,6 +53,7 @@ pycrypto==2.6.1 pyflakes==1.0.0 pyparsing==2.1.0 pyrsistent==0.11.12 +osc-lib==1.2.0 python-cinderclient==1.9.0 python-glanceclient==2.5.0 python-heatclient==1.5.0 @@ -60,7 +61,7 @@ python-keystoneclient==3.6.0 python-mimeparse==1.5.1 python-neutronclient==6.0.0 python-novaclient==6.0.0 -python-openstackclient==3.3.0 +python-openstackclient==3.7.0 python-subunit==1.2.0 python-swiftclient==3.0.0 pytz==2015.7 @@ -86,3 +87,5 @@ docker-py==1.10.6 flasgger==0.5.13 flask-restful-swagger==0.19 SQLAlchemy==1.1.4 +zmq==0.0.0 +pika==0.10.0 diff --git a/tests/unit/apiserver/__init__.py b/tests/unit/apiserver/__init__.py new file mode 100644 index 000000000..021415296 --- /dev/null +++ b/tests/unit/apiserver/__init__.py @@ -0,0 +1,35 @@ +from __future__ import absolute_import + +import os +import unittest +import tempfile + +from oslo_serialization import jsonutils + +from yardstick.common import constants as consts + + +class APITestCase(unittest.TestCase): + + def setUp(self): + self.db_fd, self.db_path = tempfile.mkstemp() + consts.SQLITE = 'sqlite:///{}'.format(self.db_path) + from api import server + + server.app.config['TESTING'] = True + self.app = server.app.test_client() + + server.init_db() + + def tearDown(self): + os.close(self.db_fd) + os.unlink(self.db_path) + + def _post(self, url, data): + headers = {'Content-Type': 'application/json'} + resp = self.app.post(url, data=jsonutils.dumps(data), headers=headers) + return jsonutils.loads(resp.data) + + def _get(self, url): + resp = self.app.get(url) + return jsonutils.loads(resp.data) diff --git a/tests/unit/apiserver/resources/__init__.py b/tests/unit/apiserver/resources/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/unit/apiserver/resources/__init__.py diff --git a/tests/unit/apiserver/resources/test_env_action.py b/tests/unit/apiserver/resources/test_env_action.py new file mode 100644 index 000000000..e8f99b706 --- /dev/null +++ b/tests/unit/apiserver/resources/test_env_action.py @@ -0,0 +1,32 @@ +from __future__ import absolute_import + +import time +import unittest + +from tests.unit.apiserver import APITestCase + + +class EnvTestCase(APITestCase): + + def test_create_grafana(self): + url = 'yardstick/env/action' + data = dict(action='createGrafanaContainer') + resp = self._post(url, data) + + time.sleep(1) + + task_id = resp['result']['task_id'] + url = '/yardstick/asynctask?task_id={}'.format(task_id) + resp = self._get(url) + + time.sleep(2) + + self.assertTrue(u'status' in resp) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/api/utils/test_common.py b/tests/unit/apiserver/utils/test_common.py index acf6e41b1..acf6e41b1 100644 --- a/tests/unit/api/utils/test_common.py +++ b/tests/unit/apiserver/utils/test_common.py diff --git a/tests/unit/api/utils/test_influx.py b/tests/unit/apiserver/utils/test_influx.py index 90aef2cab..aff0cab5c 100644 --- a/tests/unit/api/utils/test_influx.py +++ b/tests/unit/apiserver/utils/test_influx.py @@ -9,8 +9,6 @@ from __future__ import absolute_import import unittest import mock -import uuid -import datetime from api.utils import influx @@ -41,33 +39,6 @@ class GetIpTestCase(unittest.TestCase): 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') diff --git a/tests/unit/benchmark/contexts/standalone_duplicate_sample.yaml b/tests/unit/benchmark/contexts/standalone_duplicate_sample.yaml new file mode 100644 index 000000000..e468d0465 --- /dev/null +++ b/tests/unit/benchmark/contexts/standalone_duplicate_sample.yaml @@ -0,0 +1,135 @@ +# Copyright (c) 2016-2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +# Sample config file about the POD information, including the +# name/IP/user/ssh key of Bare Metal and Controllers/Computes +# +# The options of this config file include: +# name: the name of this node +# role: node's role, support role: Master/Controller/Comupte/BareMetal +# ip: the node's IP address +# user: the username for login +# key_filename:the path of the private key file for login + +nodes: +- + name: node1 + role: TrafficGen + ip: 1.1.1.1 + user: root + password: r00t + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:05:00.0" + driver: i40e + dpdk_port_num: 0 + local_ip: "152.16.100.20" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:01" + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:05:00.1" + driver: i40e + dpdk_port_num: 1 + local_ip: "152.16.100.21" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:02" +- + name: node2 + role: nfvi_node + class: OvsDpdk + ip: 1.1.1.2 + user: root + password: r00t + vports: + - dpdkvhostuser0 + - dpdkvhostuser1 + vports_mac: + - "00:00:00:00:00:03" + - "00:00:00:00:00:04" + phy_ports: # Physical ports to configure sriov + - "0000:05:00.0" + - "0000:05:00.1" + flow: + - ovs-ofctl add-flow br0 in_port=1,action=output:3 + - ovs-ofctl add-flow br0 in_port=3,action=output:1 + - ovs-ofctl add-flow br0 in_port=4,action=output:2 + - ovs-ofctl add-flow br0 in_port=2,action=output:4 + phy_driver: i40e # kernel driver + images: "/var/lib/libvirt/images/ubuntu.qcow2" +- + name: node2 + role: nfvi_node + class: OvsDpdk + ip: 1.1.1.5 + user: root + password: r00t + vports: + - dpdkvhostuser0 + - dpdkvhostuser1 + vports_mac: + - "00:00:00:00:00:03" + - "00:00:00:00:00:04" + phy_ports: # Physical ports to configure sriov + - "0000:05:00.0" + - "0000:05:00.1" + flow: + - ovs-ofctl add-flow br0 in_port=1,action=output:3 + - ovs-ofctl add-flow br0 in_port=3,action=output:1 + - ovs-ofctl add-flow br0 in_port=4,action=output:2 + - ovs-ofctl add-flow br0 in_port=2,action=output:4 + phy_driver: i40e # kernel driver + images: "/var/lib/libvirt/images/ubuntu.qcow2" + +- + name: node3 + role: vnf + ip: 1.1.1.3 + user: root + password: r00t + host: 1.1.1.1 + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:00:04.0" + driver: virtio-pci + dpdk_port_num: 0 + local_ip: "152.16.100.19" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:05" + + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:00:05.0" + driver: virtio-pci + dpdk_port_num: 1 + local_ip: "152.16.40.19" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:06" + routing_table: + - network: "152.16.100.20" + netmask: "255.255.255.0" + gateway: "152.16.100.20" + if: "xe0" + - network: "152.16.40.20" + netmask: "255.255.255.0" + gateway: "152.16.40.20" + if: "xe1" + nd_route_tbl: + - network: "0064:ff9b:0:0:0:0:9810:6414" + netmask: "112" + gateway: "0064:ff9b:0:0:0:0:9810:6414" + if: "xe0" + - network: "0064:ff9b:0:0:0:0:9810:2814" + netmask: "112" + gateway: "0064:ff9b:0:0:0:0:9810:2814" + if: "xe1" diff --git a/tests/unit/benchmark/contexts/standalone_sample.yaml b/tests/unit/benchmark/contexts/standalone_sample.yaml new file mode 100644 index 000000000..95e12d62f --- /dev/null +++ b/tests/unit/benchmark/contexts/standalone_sample.yaml @@ -0,0 +1,112 @@ +# Copyright (c) 2016-2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +# Sample config file about the POD information, including the +# name/IP/user/ssh key of Bare Metal and Controllers/Computes +# +# The options of this config file include: +# name: the name of this node +# role: node's role, support role: Master/Controller/Comupte/BareMetal +# ip: the node's IP address +# user: the username for login +# key_filename:the path of the private key file for login + +nodes: +- + name: node1 + role: TrafficGen + ip: 1.1.1.1 + user: root + password: r00t + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:05:00.0" + driver: i40e + dpdk_port_num: 0 + local_ip: "152.16.100.20" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:01" + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:05:00.1" + driver: i40e + dpdk_port_num: 1 + local_ip: "152.16.100.21" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:02" +- + name: node2 + role: nfvi_node + class: OvsDpdk + ip: 1.1.1.2 + user: root + password: r00t + vports: + - dpdkvhostuser0 + - dpdkvhostuser1 + vports_mac: + - "00:00:00:00:00:03" + - "00:00:00:00:00:04" + phy_ports: # Physical ports to configure sriov + - "0000:05:00.0" + - "0000:05:00.1" + flow: + - ovs-ofctl add-flow br0 in_port=1,action=output:3 + - ovs-ofctl add-flow br0 in_port=3,action=output:1 + - ovs-ofctl add-flow br0 in_port=4,action=output:2 + - ovs-ofctl add-flow br0 in_port=2,action=output:4 + phy_driver: i40e # kernel driver + images: "/var/lib/libvirt/images/ubuntu.qcow2" + +- + name: node3 + role: vnf + ip: 1.1.1.3 + user: root + password: r00t + host: 1.1.1.1 + interfaces: + xe0: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:00:04.0" + driver: virtio-pci + dpdk_port_num: 0 + local_ip: "152.16.100.19" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:05" + + xe1: # logical name from topology.yaml and vnfd.yaml + vpci: "0000:00:05.0" + driver: virtio-pci + dpdk_port_num: 1 + local_ip: "152.16.40.19" + netmask: "255.255.255.0" + local_mac: "00:00:00:00:00:06" + routing_table: + - network: "152.16.100.20" + netmask: "255.255.255.0" + gateway: "152.16.100.20" + if: "xe0" + - network: "152.16.40.20" + netmask: "255.255.255.0" + gateway: "152.16.40.20" + if: "xe1" + nd_route_tbl: + - network: "0064:ff9b:0:0:0:0:9810:6414" + netmask: "112" + gateway: "0064:ff9b:0:0:0:0:9810:6414" + if: "xe0" + - network: "0064:ff9b:0:0:0:0:9810:2814" + netmask: "112" + gateway: "0064:ff9b:0:0:0:0:9810:2814" + if: "xe1" diff --git a/tests/unit/benchmark/contexts/test_node.py b/tests/unit/benchmark/contexts/test_node.py index de5ba7066..64fe4a566 100644 --- a/tests/unit/benchmark/contexts/test_node.py +++ b/tests/unit/benchmark/contexts/test_node.py @@ -42,7 +42,7 @@ class NodeContextTestCase(unittest.TestCase): 'file': self._get_file_abspath("error_file") } - self.assertRaises(SystemExit, self.test_context.init, attrs) + self.assertRaises(IOError, self.test_context.init, attrs) def test_successful_init(self): @@ -100,7 +100,7 @@ class NodeContextTestCase(unittest.TestCase): attr_name = 'node1.foo' - self.assertRaises(SystemExit, self.test_context._get_server, attr_name) + self.assertRaises(ValueError, self.test_context._get_server, attr_name) def test__get_server_found(self): diff --git a/tests/unit/benchmark/contexts/test_standalone.py b/tests/unit/benchmark/contexts/test_standalone.py new file mode 100644 index 000000000..687ef7305 --- /dev/null +++ b/tests/unit/benchmark/contexts/test_standalone.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python + +# Copyright (c) 2016-2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Unittest for yardstick.benchmark.contexts.standalone + +from __future__ import absolute_import +import os +import unittest + +from yardstick.benchmark.contexts import standalone + + +class StandaloneContextTestCase(unittest.TestCase): + + NODES_SAMPLE = "standalone_sample.yaml" + NODES_DUPLICATE_SAMPLE = "standalone_duplicate_sample.yaml" + + def setUp(self): + self.test_context = standalone.StandaloneContext() + + def test_construct(self): + + self.assertIsNone(self.test_context.name) + self.assertIsNone(self.test_context.file_path) + self.assertEqual(self.test_context.nodes, []) + self.assertEqual(self.test_context.nfvi_node, []) + + def test_unsuccessful_init(self): + + attrs = { + 'name': 'foo', + 'file': self._get_file_abspath("error_file") + } + + self.assertRaises(IOError, self.test_context.init, attrs) + + def test_successful_init(self): + + attrs = { + 'name': 'foo', + 'file': self._get_file_abspath(self.NODES_SAMPLE) + } + + self.test_context.init(attrs) + + self.assertEqual(self.test_context.name, "foo") + self.assertEqual(len(self.test_context.nodes), 3) + self.assertEqual(len(self.test_context.nfvi_node), 1) + self.assertEqual(self.test_context.nfvi_node[0]["name"], "node2") + + def test__get_server_with_dic_attr_name(self): + + attrs = { + 'name': 'foo', + 'file': self._get_file_abspath(self.NODES_SAMPLE) + } + + self.test_context.init(attrs) + + attr_name = {'name': 'foo.bar'} + result = self.test_context._get_server(attr_name) + + self.assertEqual(result, None) + + def test__get_server_not_found(self): + + attrs = { + 'name': 'foo', + 'file': self._get_file_abspath(self.NODES_SAMPLE) + } + + self.test_context.init(attrs) + + attr_name = 'bar.foo' + result = self.test_context._get_server(attr_name) + + self.assertEqual(result, None) + + def test__get_server_duplicate(self): + + attrs = { + 'name': 'foo', + 'file': self._get_file_abspath(self.NODES_DUPLICATE_SAMPLE) + } + + self.test_context.init(attrs) + + attr_name = 'node2.foo' + + self.assertRaises(ValueError, self.test_context._get_server, attr_name) + + def test__get_server_found(self): + + attrs = { + 'name': 'foo', + 'file': self._get_file_abspath(self.NODES_SAMPLE) + } + + self.test_context.init(attrs) + + attr_name = 'node1.foo' + result = self.test_context._get_server(attr_name) + + self.assertEqual(result['ip'], '1.1.1.1') + self.assertEqual(result['name'], 'node1.foo') + self.assertEqual(result['user'], 'root') + + def test_deploy(self): + self.assertIsNone(self.test_context.deploy()) + + def test_undeploy(self): + self.assertIsNone(self.test_context.undeploy()) + + def _get_file_abspath(self, filename): + curr_path = os.path.dirname(os.path.abspath(__file__)) + file_path = os.path.join(curr_path, filename) + return file_path diff --git a/tests/unit/network_services/__init__.py b/tests/unit/network_services/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/unit/network_services/__init__.py diff --git a/tests/unit/network_services/collector/__init__.py b/tests/unit/network_services/collector/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/unit/network_services/collector/__init__.py diff --git a/tests/unit/network_services/collector/test_publisher.py b/tests/unit/network_services/collector/test_publisher.py new file mode 100644 index 000000000..d1e56e114 --- /dev/null +++ b/tests/unit/network_services/collector/test_publisher.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +# Copyright (c) 2016-2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Unittest for yardstick.network_services.collector.publisher + +from __future__ import absolute_import +import unittest + +from yardstick.network_services.collector import publisher + + +class PublisherTestCase(unittest.TestCase): + + def setUp(self): + self.test_publisher = publisher.Publisher() + + def test_successful_init(self): + pass + + def test_unsuccessful_init(self): + pass + + def test_start(self): + self.assertIsNone(self.test_publisher.start()) + + def test_stop(self): + self.assertIsNone(self.test_publisher.stop()) diff --git a/tests/unit/network_services/collector/test_subscriber.py b/tests/unit/network_services/collector/test_subscriber.py new file mode 100644 index 000000000..373f5dccf --- /dev/null +++ b/tests/unit/network_services/collector/test_subscriber.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python + +# Copyright (c) 2016-2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Unittest for yardstick.network_services.collector.subscriber + +from __future__ import absolute_import +import unittest + +from yardstick.network_services.collector import subscriber + + +class CollectorTestCase(unittest.TestCase): + + TRAFFIC_PROFILE = {} + VNFS = {} + + def setUp(self): + self.test_subscriber = subscriber.Collector(self.TRAFFIC_PROFILE, + self.VNFS) + + def test_successful_init(self): + + self.assertEqual(self.test_subscriber.traffic_profile, {}) + self.assertEqual(self.test_subscriber.service, {}) + + def test_unsuccessful_init(self): + pass + + def test_start(self): + self.assertIsNone(self.test_subscriber.start()) + + def test_stop(self): + self.assertIsNone(self.test_subscriber.stop()) + + def test_get_kpi(self): + + class VnfAprrox(object): + def __init__(self): + self.result = {} + self.name = "vnf__1" + + def collect_kpi(self): + self.result = {'pkt_in_up_stream': 100, + 'pkt_drop_up_stream': 5, + 'pkt_in_down_stream': 50, + 'pkt_drop_down_stream': 40} + return self.result + + vnf = VnfAprrox() + result = self.test_subscriber.get_kpi(vnf) + + self.assertEqual(result["vnf__1"]["pkt_in_up_stream"], 100) + self.assertEqual(result["vnf__1"]["pkt_drop_up_stream"], 5) + self.assertEqual(result["vnf__1"]["pkt_in_down_stream"], 50) + self.assertEqual(result["vnf__1"]["pkt_drop_down_stream"], 40) diff --git a/yardstick/benchmark/contexts/base.py b/yardstick/benchmark/contexts/base.py index 054ce4236..9f2b21537 100644 --- a/yardstick/benchmark/contexts/base.py +++ b/yardstick/benchmark/contexts/base.py @@ -15,7 +15,7 @@ import yardstick.common.utils as utils @six.add_metaclass(abc.ABCMeta) class Context(object): - '''Class that represents a context in the logical model''' + """Class that represents a context in the logical model""" list = [] def __init__(self): @@ -27,7 +27,7 @@ class Context(object): @staticmethod def get_cls(context_type): - '''Return class of specified type.''' + """Return class of specified type.""" for context in utils.itersubclasses(Context): if context_type == context.__context_type__: return context @@ -41,23 +41,23 @@ class Context(object): @abc.abstractmethod def deploy(self): - '''Deploy context.''' + """Deploy context.""" @abc.abstractmethod def undeploy(self): - '''Undeploy context.''' + """Undeploy context.""" @abc.abstractmethod def _get_server(self, attr_name): - '''get server info by name from context - ''' + """get server info by name from context + """ @staticmethod def get_server(attr_name): - '''lookup server info by name from context + """lookup server info by name from context attr_name: either a name for a server created by yardstick or a dict with attribute name mapping when using external heat templates - ''' + """ server = None for context in Context.list: server = context._get_server(attr_name) diff --git a/yardstick/benchmark/contexts/dummy.py b/yardstick/benchmark/contexts/dummy.py index 0e76b5a82..f7530035c 100644 --- a/yardstick/benchmark/contexts/dummy.py +++ b/yardstick/benchmark/contexts/dummy.py @@ -17,7 +17,7 @@ LOG = logging.getLogger(__name__) class DummyContext(Context): - '''Class that handle dummy info''' + """Class that handle dummy info""" __context_type__ = "Dummy" @@ -28,11 +28,11 @@ class DummyContext(Context): pass def deploy(self): - '''don't need to deploy''' + """don't need to deploy""" pass def undeploy(self): - '''don't need to undeploy''' + """don't need to undeploy""" pass def _get_server(self, attr_name): diff --git a/yardstick/benchmark/contexts/heat.py b/yardstick/benchmark/contexts/heat.py index 0b2fbdcd6..0346efcf4 100644 --- a/yardstick/benchmark/contexts/heat.py +++ b/yardstick/benchmark/contexts/heat.py @@ -31,7 +31,7 @@ LOG = logging.getLogger(__name__) class HeatContext(Context): - '''Class that represents a context in the logical model''' + """Class that represents a context in the logical model""" __context_type__ = "Heat" @@ -58,7 +58,7 @@ class HeatContext(Context): super(self.__class__, self).__init__() def init(self, attrs): - '''initializes itself from the supplied arguments''' + """initializes itself from the supplied arguments""" self.name = attrs["name"] if "user" in attrs: @@ -101,21 +101,21 @@ class HeatContext(Context): @property def image(self): - '''returns application's default image name''' + """returns application's default image name""" return self._image @property def flavor(self): - '''returns application's default flavor name''' + """returns application's default flavor name""" return self._flavor @property def user(self): - '''return login user name corresponding to image''' + """return login user name corresponding to image""" return self._user def _add_resources_to_template(self, template): - '''add to the template the resources represented by this context''' + """add to the template the resources represented by this context""" template.add_keypair(self.keypair_name, self.key_uuid) template.add_security_group(self.secgroup_name) @@ -200,7 +200,7 @@ class HeatContext(Context): server.add_to_template(template, self.networks, {}) def deploy(self): - '''deploys template into a stack using cloud''' + """deploys template into a stack using cloud""" print("Deploying context '%s'" % self.name) heat_template = HeatTemplate(self.name, self.template_file, @@ -232,7 +232,7 @@ class HeatContext(Context): print("Context '%s' deployed" % self.name) def undeploy(self): - '''undeploys stack from cloud''' + """undeploys stack from cloud""" if self.stack: print("Undeploying context '%s'" % self.name) self.stack.delete() @@ -247,10 +247,10 @@ class HeatContext(Context): LOG.exception("Key filename %s", self.key_filename) def _get_server(self, attr_name): - '''lookup server info by name from context + """lookup server info by name from context attr_name: either a name for a server created by yardstick or a dict with attribute name mapping when using external heat templates - ''' + """ key_filename = pkg_resources.resource_filename( 'yardstick.resources', 'files/yardstick_key-' + get_short_key_uuid(self.key_uuid)) diff --git a/yardstick/benchmark/contexts/model.py b/yardstick/benchmark/contexts/model.py index 1d0a5a133..636abfa35 100644 --- a/yardstick/benchmark/contexts/model.py +++ b/yardstick/benchmark/contexts/model.py @@ -15,9 +15,9 @@ from six.moves import range class Object(object): - '''Base class for classes in the logical model + """Base class for classes in the logical model Contains common attributes and methods - ''' + """ def __init__(self, name, context): # model identities and reference @@ -30,15 +30,15 @@ class Object(object): @property def dn(self): - '''returns distinguished name for object''' + """returns distinguished name for object""" return self.name + "." + self._context.name class PlacementGroup(Object): - '''Class that represents a placement group in the logical model + """Class that represents a placement group in the logical model Concept comes from the OVF specification. Policy should be one of "availability" or "affinity (there are more but they are not supported)" - ''' + """ map = {} def __init__(self, name, context, policy): @@ -63,7 +63,7 @@ class PlacementGroup(Object): class Router(Object): - '''Class that represents a router in the logical model''' + """Class that represents a router in the logical model""" def __init__(self, name, network_name, context, external_gateway_info): super(self.__class__, self).__init__(name, context) @@ -74,7 +74,7 @@ class Router(Object): class Network(Object): - '''Class that represents a network in the logical model''' + """Class that represents a network in the logical model""" list = [] def __init__(self, name, context, attrs): @@ -91,22 +91,22 @@ class Network(Object): Network.list.append(self) def has_route_to(self, network_name): - '''determines if this network has a route to the named network''' + """determines if this network has a route to the named network""" if self.router and self.router.external_gateway_info == network_name: return True return False @staticmethod def find_by_route_to(external_network): - '''finds a network that has a route to the specified network''' + """finds a network that has a route to the specified network""" for network in Network.list: if network.has_route_to(external_network): return network @staticmethod def find_external_network(): - '''return the name of an external network some network in this - context has a route to''' + """return the name of an external network some network in this + context has a route to""" for network in Network.list: if network.router: return network.router.external_gateway_info @@ -114,7 +114,7 @@ class Network(Object): class Server(Object): - '''Class that represents a server in the logical model''' + """Class that represents a server in the logical model""" list = [] def __init__(self, name, context, attrs): @@ -171,7 +171,7 @@ class Server(Object): @property def image(self): - '''returns a server's image name''' + """returns a server's image name""" if self._image: return self._image else: @@ -179,14 +179,14 @@ class Server(Object): @property def flavor(self): - '''returns a server's flavor name''' + """returns a server's flavor name""" if self._flavor: return self._flavor else: return self._context.flavor def _add_instance(self, template, server_name, networks, scheduler_hints): - '''adds to the template one server and corresponding resources''' + """adds to the template one server and corresponding resources""" port_name_list = [] for network in networks: port_name = server_name + "-" + network.name + "-port" @@ -219,7 +219,7 @@ class Server(Object): scheduler_hints=scheduler_hints) def add_to_template(self, template, networks, scheduler_hints=None): - '''adds to the template one or more servers (instances)''' + """adds to the template one or more servers (instances)""" if self.instances == 1: server_name = self.stack_name self._add_instance(template, server_name, networks, @@ -233,9 +233,9 @@ class Server(Object): def update_scheduler_hints(scheduler_hints, added_servers, placement_group): - ''' update scheduler hints from server's placement configuration + """ update scheduler hints from server's placement configuration TODO: this code is openstack specific and should move somewhere else - ''' + """ if placement_group.policy == "affinity": if "same_host" in scheduler_hints: host_list = scheduler_hints["same_host"] diff --git a/yardstick/benchmark/contexts/node.py b/yardstick/benchmark/contexts/node.py index 6db51cccb..9242e2727 100644 --- a/yardstick/benchmark/contexts/node.py +++ b/yardstick/benchmark/contexts/node.py @@ -8,10 +8,11 @@ ############################################################################## from __future__ import absolute_import -import sys +import logging +import errno import os +import collections import yaml -import logging from yardstick.benchmark.contexts.base import Context from yardstick.definitions import YARDSTICK_ROOT_PATH @@ -20,7 +21,7 @@ LOG = logging.getLogger(__name__) class NodeContext(Context): - '''Class that handle nodes info''' + """Class that handle nodes info""" __context_type__ = "Node" @@ -33,20 +34,28 @@ class NodeContext(Context): self.baremetals = [] super(self.__class__, self).__init__() + def read_config_file(self): + """Read from config file""" + + with open(self.file_path) as stream: + LOG.info("Parsing pod file: %s", self.file_path) + cfg = yaml.load(stream) + return cfg + def init(self, attrs): - '''initializes itself from the supplied arguments''' + """initializes itself from the supplied arguments""" self.name = attrs["name"] self.file_path = attrs.get("file", "pod.yaml") - if not os.path.exists(self.file_path): - self.file_path = os.path.join(YARDSTICK_ROOT_PATH, self.file_path) - - LOG.info("Parsing pod file: %s", self.file_path) try: - with open(self.file_path) as stream: - cfg = yaml.load(stream) + cfg = self.read_config_file() except IOError as ioerror: - sys.exit(ioerror) + if ioerror.errno == errno.ENOENT: + self.file_path = \ + os.path.join(YARDSTICK_ROOT_PATH, self.file_path) + cfg = self.read_config_file() + else: + raise self.nodes.extend(cfg["nodes"]) self.controllers.extend([node for node in cfg["nodes"] @@ -61,34 +70,39 @@ class NodeContext(Context): LOG.debug("BareMetals: %r", self.baremetals) def deploy(self): - '''don't need to deploy''' + """don't need to deploy""" pass def undeploy(self): - '''don't need to undeploy''' + """don't need to undeploy""" pass def _get_server(self, attr_name): - '''lookup server info by name from context + """lookup server info by name from context attr_name: a name for a server listed in nodes config file - ''' - if type(attr_name) is dict: + """ + if isinstance(attr_name, collections.Mapping): return None if self.name != attr_name.split(".")[1]: return None node_name = attr_name.split(".")[0] - nodes = [n for n in self.nodes - if n["name"] == node_name] - if len(nodes) == 0: + matching_nodes = (n for n in self.nodes if n["name"] == node_name) + + try: + # A clone is created in order to avoid affecting the + # original one. + node = dict(next(matching_nodes)) + except StopIteration: return None - elif len(nodes) > 1: - LOG.error("Duplicate nodes!!!") - LOG.error("Nodes: %r", nodes) - sys.exit(-1) - - # A clone is created in order to avoid affecting the - # original one. - node = dict(nodes[0]) + + try: + duplicate = next(matching_nodes) + except StopIteration: + pass + else: + raise ValueError("Duplicate nodes!!! Nodes: %s %s", + (matching_nodes, duplicate)) + node["name"] = attr_name return node diff --git a/yardstick/benchmark/contexts/standalone.py b/yardstick/benchmark/contexts/standalone.py new file mode 100644 index 000000000..c1d963f50 --- /dev/null +++ b/yardstick/benchmark/contexts/standalone.py @@ -0,0 +1,116 @@ +# Copyright (c) 2016-2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""This module handle non managed standalone virtualization node.""" + +from __future__ import absolute_import +import logging +import errno +import collections +import yaml + +from yardstick.benchmark.contexts.base import Context +from yardstick.definitions import YARDSTICK_ROOT_PATH + +LOG = logging.getLogger(__name__) + + +class StandaloneContext(Context): + """ This class handles standalone nodes - VM running on Non-Managed NFVi + Configuration: vswitch, ovs, ovs-dpdk, sr-iov, linuxbridge + """ + + __context_type__ = "Standalone" + + def __init__(self): + self.name = None + self.file_path = None + self.nodes = [] + self.nfvi_node = [] + super(self.__class__, self).__init__() + + def read_config_file(self): + """Read from config file""" + + with open(self.file_path) as stream: + LOG.info("Parsing pod file: %s", self.file_path) + cfg = yaml.load(stream) + return cfg + + def init(self, attrs): + """initializes itself from the supplied arguments""" + + self.name = attrs["name"] + self.file_path = attrs.get("file", "pod.yaml") + LOG.info("Parsing pod file: %s", self.file_path) + + try: + cfg = self.read_config_file() + except IOError as ioerror: + if ioerror.errno == errno.ENOENT: + self.file_path = YARDSTICK_ROOT_PATH + self.file_path + cfg = self.read_config_file() + else: + raise + + self.nodes.extend(cfg["nodes"]) + self.nfvi_node.extend([node for node in cfg["nodes"] + if node["role"] == "nfvi_node"]) + LOG.debug("Nodes: %r", self.nodes) + LOG.debug("NFVi Node: %r", self.nfvi_node) + + def deploy(self): + """don't need to deploy""" + + # Todo: NFVi deploy (sriov, vswitch, ovs etc) based on the config. + pass + + def undeploy(self): + """don't need to undeploy""" + + # Todo: NFVi undeploy (sriov, vswitch, ovs etc) based on the config. + pass + + def _get_server(self, attr_name): + """lookup server info by name from context + + Keyword arguments: + attr_name -- A name for a server listed in nodes config file + """ + + if isinstance(attr_name, collections.Mapping): + return None + + if self.name.split("-")[0] != attr_name.split(".")[1]: + return None + + node_name = attr_name.split(".")[0] + matching_nodes = (n for n in self.nodes if n["name"] == node_name) + + try: + # A clone is created in order to avoid affecting the + # original one. + node = dict(next(matching_nodes)) + except StopIteration: + return None + + try: + duplicate = next(matching_nodes) + except StopIteration: + pass + else: + raise ValueError("Duplicate nodes!!! Nodes: %s %s", + (matching_nodes, duplicate)) + + node["name"] = attr_name + return node diff --git a/yardstick/benchmark/core/__init__.py b/yardstick/benchmark/core/__init__.py index 12c83f87e..161e448cc 100644 --- a/yardstick/benchmark/core/__init__.py +++ b/yardstick/benchmark/core/__init__.py @@ -32,7 +32,7 @@ class Param(object): def print_hbar(barlen): - '''print to stdout a horizontal bar''' + """print to stdout a horizontal bar""" print("+"), print("-" * barlen), print("+") diff --git a/yardstick/benchmark/core/runner.py b/yardstick/benchmark/core/runner.py index 5f8132da8..b9c22cbc9 100644 --- a/yardstick/benchmark/core/runner.py +++ b/yardstick/benchmark/core/runner.py @@ -16,13 +16,13 @@ from yardstick.benchmark.core import print_hbar class Runners(object): - '''Runner commands. + """Runner commands. Set of commands to discover and display runner types. - ''' + """ def list_all(self, args): - '''List existing runner types''' + """List existing runner types""" types = Runner.get_types() print_hbar(78) print("| %-16s | %-60s" % ("Type", "Description")) @@ -33,6 +33,6 @@ class Runners(object): print_hbar(78) def show(self, args): - '''Show details of a specific runner type''' + """Show details of a specific runner type""" rtype = Runner.get_cls(args.type[0]) print(rtype.__doc__) diff --git a/yardstick/benchmark/core/scenario.py b/yardstick/benchmark/core/scenario.py index 15335afd4..a9d933faf 100644 --- a/yardstick/benchmark/core/scenario.py +++ b/yardstick/benchmark/core/scenario.py @@ -16,13 +16,13 @@ from yardstick.benchmark.core import print_hbar class Scenarios(object): - '''Scenario commands. + """Scenario commands. Set of commands to discover and display scenario types. - ''' + """ def list_all(self, args): - '''List existing scenario types''' + """List existing scenario types""" types = Scenario.get_types() print_hbar(78) print("| %-16s | %-60s" % ("Type", "Description")) @@ -33,6 +33,6 @@ class Scenarios(object): print_hbar(78) def show(self, args): - '''Show details of a specific scenario type''' + """Show details of a specific scenario type""" stype = Scenario.get_cls(args.type[0]) print(stype.__doc__) diff --git a/yardstick/benchmark/core/task.py b/yardstick/benchmark/core/task.py index 1a3d21934..14b46867c 100644 --- a/yardstick/benchmark/core/task.py +++ b/yardstick/benchmark/core/task.py @@ -34,13 +34,13 @@ LOG = logging.getLogger(__name__) class Task(object): # pragma: no cover - '''Task commands. + """Task commands. Set of commands to manage benchmark tasks. - ''' + """ def start(self, args, **kwargs): - '''Start a benchmark scenario.''' + """Start a benchmark scenario.""" atexit.register(atexit_handler) @@ -101,7 +101,7 @@ class Task(object): # pragma: no cover print("Done, exiting") def _run(self, scenarios, run_in_parallel, output_file): - '''Deploys context and calls runners''' + """Deploys context and calls runners""" for context in Context.list: context.deploy() @@ -151,7 +151,7 @@ class Task(object): # pragma: no cover class TaskParser(object): # pragma: no cover - '''Parser for task config files in yaml format''' + """Parser for task config files in yaml format""" def __init__(self, path): self.path = path @@ -181,8 +181,8 @@ class TaskParser(object): # pragma: no cover return task_args, task_args_fnames def parse_suite(self): - '''parse the suite file and return a list of task config file paths - and lists of optional parameters if present''' + """parse the suite file and return a list of task config file paths + and lists of optional parameters if present""" LOG.info("\nParsing suite file:%s", self.path) try: @@ -228,7 +228,7 @@ class TaskParser(object): # pragma: no cover return valid_task_files, valid_task_args, valid_task_args_fnames def parse_task(self, task_id, task_args=None, task_args_file=None): - '''parses the task file and return an context and scenario instances''' + """parses the task file and return an context and scenario instances""" print("Parsing task config:", self.path) try: @@ -296,7 +296,8 @@ class TaskParser(object): # pragma: no cover change_server_name(scenario, name_suffix) try: - change_server_name(scenario['nodes'], name_suffix) + for node in scenario['nodes']: + scenario['nodes'][node] += name_suffix except KeyError: pass @@ -304,14 +305,14 @@ class TaskParser(object): # pragma: no cover return cfg["scenarios"], run_in_parallel, meet_precondition def _check_schema(self, cfg_schema, schema_type): - '''Check if config file is using the correct schema type''' + """Check if config file is using the correct schema type""" if cfg_schema != "yardstick:" + schema_type + ":0.1": sys.exit("error: file %s has unknown schema %s" % (self.path, cfg_schema)) def _check_precondition(self, cfg): - '''Check if the envrionment meet the preconditon''' + """Check if the envrionment meet the preconditon""" if "precondition" in cfg: precondition = cfg["precondition"] @@ -344,7 +345,7 @@ class TaskParser(object): # pragma: no cover def atexit_handler(): - '''handler for process termination''' + """handler for process termination""" base_runner.Runner.terminate_all() if len(Context.list) > 0: @@ -354,7 +355,7 @@ def atexit_handler(): def is_ip_addr(addr): - '''check if string addr is an IP address''' + """check if string addr is an IP address""" try: ipaddress.ip_address(addr.encode('utf-8')) return True @@ -363,12 +364,12 @@ def is_ip_addr(addr): def _is_same_heat_context(host_attr, target_attr): - '''check if two servers are in the same heat context + """check if two servers are in the same heat context host_attr: either a name for a server created by yardstick or a dict with attribute name mapping when using external heat templates target_attr: either a name for a server created by yardstick or a dict with attribute name mapping when using external heat templates - ''' + """ host = None target = None for context in Context.list: @@ -398,7 +399,7 @@ def _is_background_scenario(scenario): def run_one_scenario(scenario_cfg, output_file): - '''run one scenario using context''' + """run one scenario using context""" runner_cfg = scenario_cfg["runner"] runner_cfg['output_filename'] = output_file @@ -446,7 +447,7 @@ def run_one_scenario(scenario_cfg, output_file): def parse_nodes_with_context(scenario_cfg): - '''paras the 'nodes' fields in scenario ''' + """paras the 'nodes' fields in scenario """ nodes = scenario_cfg["nodes"] nodes_cfg = {} @@ -457,7 +458,7 @@ def parse_nodes_with_context(scenario_cfg): def runner_join(runner): - '''join (wait for) a runner, exit process at runner failure''' + """join (wait for) a runner, exit process at runner failure""" status = runner.join() base_runner.Runner.release(runner) if status != 0: diff --git a/yardstick/benchmark/core/testcase.py b/yardstick/benchmark/core/testcase.py index 74304857f..92198bd91 100644 --- a/yardstick/benchmark/core/testcase.py +++ b/yardstick/benchmark/core/testcase.py @@ -20,17 +20,17 @@ from yardstick.definitions import YARDSTICK_ROOT_PATH class Testcase(object): - '''Testcase commands. + """Testcase commands. Set of commands to discover and display test cases. - ''' + """ def __init__(self): self.test_case_path = YARDSTICK_ROOT_PATH + 'tests/opnfv/test_cases/' self.testcase_list = [] def list_all(self, args): - '''List existing test cases''' + """List existing test cases""" try: testcase_files = os.listdir(self.test_case_path) @@ -48,7 +48,7 @@ class Testcase(object): return True def show(self, args): - '''Show details of a specific test case''' + """Show details of a specific test case""" testcase_name = args.casename[0] testcase_path = self.test_case_path + testcase_name + ".yaml" try: @@ -104,7 +104,7 @@ class Testcase(object): return description, installer_type, deploy_scenarios def _format_print(self, testcase_list): - '''format output''' + """format output""" print_hbar(88) print("| %-21s | %-60s" % ("Testcase Name", "Description")) diff --git a/yardstick/benchmark/runners/arithmetic.py b/yardstick/benchmark/runners/arithmetic.py index 956c3ffd1..d5605f755 100755 --- a/yardstick/benchmark/runners/arithmetic.py +++ b/yardstick/benchmark/runners/arithmetic.py @@ -16,13 +16,13 @@ # yardstick comment: this is a modified copy of # rally/rally/benchmark/runners/constant.py -'''A runner that every run arithmetically steps specified input value(s) to +"""A runner that every run arithmetically steps specified input value(s) to the scenario. This just means step value(s) is added to the previous value(s). It is possible to combine several named input values and run with those either as nested for loops or combine each i:th index of each "input value list" until the end of the shortest list is reached (optimally all lists should be defined with the same number of values when using such iter_type). -''' +""" from __future__ import absolute_import @@ -147,7 +147,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, class ArithmeticRunner(base.Runner): - '''Run a scenario arithmetically stepping input value(s) + """Run a scenario arithmetically stepping input value(s) Parameters interval - time to wait between each scenario invocation @@ -180,7 +180,7 @@ class ArithmeticRunner(base.Runner): default: none - name - and so on...... - ''' + """ __execution_type__ = 'Arithmetic' diff --git a/yardstick/benchmark/runners/base.py b/yardstick/benchmark/runners/base.py index 0e0292713..bf1a71cab 100755 --- a/yardstick/benchmark/runners/base.py +++ b/yardstick/benchmark/runners/base.py @@ -36,10 +36,10 @@ CONF = cfg.CONF def _output_serializer_main(filename, queue): - '''entrypoint for the singleton subprocess writing to outfile + """entrypoint for the singleton subprocess writing to outfile Use of this process enables multiple instances of a scenario without messing up the output file. - ''' + """ config = {} config["type"] = CONF.dispatcher.capitalize() config["file_path"] = filename @@ -56,7 +56,7 @@ def _output_serializer_main(filename, queue): def _execute_shell_command(command): - '''execute shell script with error handling''' + """execute shell script with error handling""" exitcode = 0 output = [] try: @@ -71,7 +71,7 @@ def _execute_shell_command(command): def _single_action(seconds, command, queue): - '''entrypoint for the single action process''' + """entrypoint for the single action process""" log.debug("single action, fires after %d seconds (from now)", seconds) time.sleep(seconds) log.debug("single action: executing command: '%s'", command) @@ -85,7 +85,7 @@ def _single_action(seconds, command, queue): def _periodic_action(interval, command, queue): - '''entrypoint for the periodic action process''' + """entrypoint for the periodic action process""" log.debug("periodic action, fires every: %d seconds", interval) time_spent = 0 while True: @@ -108,7 +108,7 @@ class Runner(object): @staticmethod def get_cls(runner_type): - '''return class of specified type''' + """return class of specified type""" for runner in utils.itersubclasses(Runner): if runner_type == runner.__execution_type__: return runner @@ -116,7 +116,7 @@ class Runner(object): @staticmethod def get_types(): - '''return a list of known runner type (class) names''' + """return a list of known runner type (class) names""" types = [] for runner in utils.itersubclasses(Runner): types.append(runner) @@ -141,7 +141,7 @@ class Runner(object): @staticmethod def release_dump_process(): - '''Release the dumper process''' + """Release the dumper process""" log.debug("Stopping dump process") if Runner.dump_process: Runner.queue.put('_TERMINATE_') @@ -150,7 +150,7 @@ class Runner(object): @staticmethod def release(runner): - '''Release the runner''' + """Release the runner""" if runner in Runner.runners: Runner.runners.remove(runner) @@ -160,13 +160,13 @@ class Runner(object): @staticmethod def terminate(runner): - '''Terminate the runner''' + """Terminate the runner""" if runner.process and runner.process.is_alive(): runner.process.terminate() @staticmethod def terminate_all(): - '''Terminate all runners (subprocesses)''' + """Terminate all runners (subprocesses)""" log.debug("Terminating all runners") # release dumper process as some errors before any runner is created @@ -194,7 +194,7 @@ class Runner(object): Runner.runners.append(self) def run_post_stop_action(self): - '''run a potentially configured post-stop action''' + """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) @@ -250,7 +250,7 @@ class Runner(object): self._run_benchmark(cls, "run", scenario_cfg, context_cfg) def abort(self): - '''Abort the execution of a scenario''' + """Abort the execution of a scenario""" self.aborted.set() def join(self, timeout=None): diff --git a/yardstick/benchmark/runners/duration.py b/yardstick/benchmark/runners/duration.py index 89cac7db8..772983cfd 100644 --- a/yardstick/benchmark/runners/duration.py +++ b/yardstick/benchmark/runners/duration.py @@ -16,8 +16,8 @@ # yardstick comment: this is a modified copy of # rally/rally/benchmark/runners/constant.py -'''A runner that runs a specific time before it returns -''' +"""A runner that runs a specific time before it returns +""" from __future__ import absolute_import import os @@ -106,7 +106,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, class DurationRunner(base.Runner): - '''Run a scenario for a certain amount of time + """Run a scenario for a certain amount of time If the scenario ends before the time has elapsed, it will be started again. @@ -119,7 +119,7 @@ If the scenario ends before the time has elapsed, it will be started again. type: int unit: seconds default: 1 sec - ''' + """ __execution_type__ = 'Duration' def _run_benchmark(self, cls, method, scenario_cfg, context_cfg): diff --git a/yardstick/benchmark/runners/iteration.py b/yardstick/benchmark/runners/iteration.py index 930f883e9..c2376af48 100644 --- a/yardstick/benchmark/runners/iteration.py +++ b/yardstick/benchmark/runners/iteration.py @@ -16,8 +16,8 @@ # yardstick comment: this is a modified copy of # rally/rally/benchmark/runners/constant.py -'''A runner that runs a configurable number of times before it returns -''' +"""A runner that runs a configurable number of times before it returns +""" from __future__ import absolute_import import os @@ -110,7 +110,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, class IterationRunner(base.Runner): - '''Run a scenario for a configurable number of times + """Run a scenario for a configurable number of times If the scenario ends before the time has elapsed, it will be started again. @@ -123,7 +123,7 @@ If the scenario ends before the time has elapsed, it will be started again. type: int unit: seconds default: 1 sec - ''' + """ __execution_type__ = 'Iteration' def _run_benchmark(self, cls, method, scenario_cfg, context_cfg): diff --git a/yardstick/benchmark/runners/sequence.py b/yardstick/benchmark/runners/sequence.py index e6abeab3c..af87c006e 100644 --- a/yardstick/benchmark/runners/sequence.py +++ b/yardstick/benchmark/runners/sequence.py @@ -16,9 +16,9 @@ # yardstick comment: this is a modified copy of # rally/rally/benchmark/runners/constant.py -'''A runner that every run changes a specified input value to the scenario. +"""A runner that every run changes a specified input value to the scenario. The input value in the sequence is specified in a list in the input file. -''' +""" from __future__ import absolute_import import os @@ -114,7 +114,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, class SequenceRunner(base.Runner): - '''Run a scenario by changing an input value defined in a list + """Run a scenario by changing an input value defined in a list Parameters interval - time to wait between each scenario invocation @@ -129,7 +129,7 @@ class SequenceRunner(base.Runner): type: [int] unit: na default: none - ''' + """ __execution_type__ = 'Sequence' diff --git a/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py b/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py index 7eb93a80f..1d632799d 100644 --- a/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py +++ b/yardstick/benchmark/scenarios/availability/attacker/attacker_baremetal.py @@ -19,7 +19,7 @@ LOG = logging.getLogger(__name__) def _execute_shell_command(command, stdin=None): - '''execute shell script with error handling''' + """execute shell script with error handling""" exitcode = 0 output = [] try: diff --git a/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py b/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py index f5f74f291..ca2324055 100644 --- a/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py +++ b/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py @@ -61,7 +61,7 @@ class BaseAttacker(object): @staticmethod def get_attacker_cls(attacker_cfg): - '''return attacker instance of specified type''' + """return attacker instance of specified type""" attacker_type = attacker_cfg['fault_type'] for attacker_cls in utils.itersubclasses(BaseAttacker): if attacker_type == attacker_cls.__attacker_type__: diff --git a/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py b/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py index a11966a12..3062037ee 100644 --- a/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py +++ b/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py @@ -77,7 +77,7 @@ class BaseMonitor(multiprocessing.Process): @staticmethod def get_monitor_cls(monitor_type): - '''return monitor class of specified type''' + """return monitor class of specified type""" for monitor in utils.itersubclasses(BaseMonitor): if monitor_type == monitor.__monitor_type__: diff --git a/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py b/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py index 6ddb73ea2..aae2daa86 100644 --- a/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py +++ b/yardstick/benchmark/scenarios/availability/monitor/monitor_command.py @@ -18,7 +18,7 @@ LOG = logging.getLogger(__name__) def _execute_shell_command(command): - '''execute shell script with error handling''' + """execute shell script with error handling""" exitcode = 0 output = [] try: diff --git a/yardstick/benchmark/scenarios/availability/operation/baseoperation.py b/yardstick/benchmark/scenarios/availability/operation/baseoperation.py index 709884b6f..be286b8fd 100644 --- a/yardstick/benchmark/scenarios/availability/operation/baseoperation.py +++ b/yardstick/benchmark/scenarios/availability/operation/baseoperation.py @@ -61,7 +61,7 @@ class BaseOperation(object): @staticmethod def get_operation_cls(type): - '''return operation instance of specified type''' + """return operation instance of specified type""" operation_type = type for operation_cls in utils.itersubclasses(BaseOperation): if operation_type == operation_cls.__operation__type__: diff --git a/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py b/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py index 70e004012..1ccd05844 100644 --- a/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py +++ b/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py @@ -69,7 +69,7 @@ class BaseResultChecker(object): @staticmethod def get_resultchecker_cls(type): - '''return resultchecker instance of specified type''' + """return resultchecker instance of specified type""" resultchecker_type = type for checker_cls in utils.itersubclasses(BaseResultChecker): if resultchecker_type == checker_cls.__result_checker__type__: diff --git a/yardstick/benchmark/scenarios/availability/serviceha.py b/yardstick/benchmark/scenarios/availability/serviceha.py index b981c8cd8..e82e69b7d 100755 --- a/yardstick/benchmark/scenarios/availability/serviceha.py +++ b/yardstick/benchmark/scenarios/availability/serviceha.py @@ -30,7 +30,7 @@ class ServiceHA(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" nodes = self.context_cfg.get("nodes", None) if nodes is None: LOG.error("the nodes info is none") @@ -77,13 +77,13 @@ class ServiceHA(base.Scenario): return def teardown(self): - '''scenario teardown''' + """scenario teardown""" for attacker in self.attackers: attacker.recover() def _test(): # pragma: no cover - '''internal test function''' + """internal test function""" host = { "ip": "10.20.0.5", "user": "root", diff --git a/yardstick/benchmark/scenarios/base.py b/yardstick/benchmark/scenarios/base.py index 5f5c07d3b..5d3c36c38 100644 --- a/yardstick/benchmark/scenarios/base.py +++ b/yardstick/benchmark/scenarios/base.py @@ -26,20 +26,20 @@ import yardstick.common.utils as utils class Scenario(object): def setup(self): - ''' default impl for scenario setup ''' + """ default impl for scenario setup """ pass def run(self, args): - ''' catcher for not implemented run methods in subclasses ''' + """ catcher for not implemented run methods in subclasses """ raise RuntimeError("run method not implemented") def teardown(self): - ''' default impl for scenario teardown ''' + """ default impl for scenario teardown """ pass @staticmethod def get_types(): - '''return a list of known runner type (class) names''' + """return a list of known runner type (class) names""" scenarios = [] for scenario in utils.itersubclasses(Scenario): scenarios.append(scenario) @@ -47,7 +47,7 @@ class Scenario(object): @staticmethod def get_cls(scenario_type): - '''return class of specified type''' + """return class of specified type""" for scenario in utils.itersubclasses(Scenario): if scenario_type == scenario.__scenario_type__: return scenario diff --git a/yardstick/benchmark/scenarios/compute/cachestat.py b/yardstick/benchmark/scenarios/compute/cachestat.py index 0f60d466e..b4c3463e5 100644 --- a/yardstick/benchmark/scenarios/compute/cachestat.py +++ b/yardstick/benchmark/scenarios/compute/cachestat.py @@ -22,7 +22,7 @@ LOG = logging.getLogger(__name__) class CACHEstat(base.Scenario): - '''Collect cache statistics. + """Collect cache statistics. This scenario reads system cache hit/miss ratio and other statistics on a Linux host. @@ -58,7 +58,7 @@ class CACHEstat(base.Scenario): some error margin depending on unusual workload types. REQUIREMENTS: CONFIG_FUNCTION_PROFILER, awk. - ''' + """ __scenario_type__ = "CACHEstat" TARGET_SCRIPT = "cache_stat.bash" diff --git a/yardstick/benchmark/scenarios/compute/cyclictest.py b/yardstick/benchmark/scenarios/compute/cyclictest.py index 76bafff2b..ae1d37324 100644 --- a/yardstick/benchmark/scenarios/compute/cyclictest.py +++ b/yardstick/benchmark/scenarios/compute/cyclictest.py @@ -141,7 +141,7 @@ class Cyclictest(base.Scenario): self._connect_guest() def setup(self): - '''scenario setup''' + """scenario setup""" setup_options = self.scenario_cfg["setup_options"] host_setup_seqs = setup_options["host_setup_seqs"] guest_setup_seqs = setup_options["guest_setup_seqs"] @@ -205,7 +205,7 @@ class Cyclictest(base.Scenario): def _test(): # pragma: no cover - '''internal test function''' + """internal test function""" key_filename = pkg_resources.resource_filename("yardstick.resources", "files/yardstick_key") ctx = { diff --git a/yardstick/benchmark/scenarios/dummy/dummy.py b/yardstick/benchmark/scenarios/dummy/dummy.py index 95146e0c5..59d177586 100644 --- a/yardstick/benchmark/scenarios/dummy/dummy.py +++ b/yardstick/benchmark/scenarios/dummy/dummy.py @@ -25,7 +25,7 @@ class Dummy(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.setup_done = True def run(self, result): diff --git a/yardstick/benchmark/scenarios/networking/iperf3.py b/yardstick/benchmark/scenarios/networking/iperf3.py index b8ec9acdf..4d4c7e7ee 100644 --- a/yardstick/benchmark/scenarios/networking/iperf3.py +++ b/yardstick/benchmark/scenarios/networking/iperf3.py @@ -167,7 +167,7 @@ For more info see http://software.es.net/iperf def _test(): - '''internal test function''' + """internal test function""" key_filename = pkg_resources.resource_filename('yardstick.resources', 'files/yardstick_key') ctx = { diff --git a/yardstick/benchmark/scenarios/networking/netperf.py b/yardstick/benchmark/scenarios/networking/netperf.py index 80dbed334..d0528826f 100755 --- a/yardstick/benchmark/scenarios/networking/netperf.py +++ b/yardstick/benchmark/scenarios/networking/netperf.py @@ -60,7 +60,7 @@ class Netperf(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.target_script = pkg_resources.resource_filename( 'yardstick.benchmark.scenarios.networking', Netperf.TARGET_SCRIPT) @@ -150,7 +150,7 @@ class Netperf(base.Scenario): def _test(): - '''internal test function''' + """internal test function""" key_filename = pkg_resources.resource_filename("yardstick.resources", "files/yardstick_key") ctx = { diff --git a/yardstick/benchmark/scenarios/networking/netperf_node.py b/yardstick/benchmark/scenarios/networking/netperf_node.py index 0cf52b8dd..fd9fa0a50 100755 --- a/yardstick/benchmark/scenarios/networking/netperf_node.py +++ b/yardstick/benchmark/scenarios/networking/netperf_node.py @@ -61,7 +61,7 @@ class NetperfNode(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.target_script = pkg_resources.resource_filename( 'yardstick.benchmark.scenarios.networking', NetperfNode.TARGET_SCRIPT) @@ -172,13 +172,13 @@ class NetperfNode(base.Scenario): (mean_latency, sla_max_mean_latency) def teardown(self): - '''remove netperf from nodes after test''' + """remove netperf from nodes after test""" self.server.execute("sudo bash netperf_remove.sh") self.client.execute("sudo bash netperf_remove.sh") def _test(): # pragma: no cover - '''internal test function''' + """internal test function""" ctx = { "host": { "ip": "192.168.10.10", diff --git a/yardstick/benchmark/scenarios/networking/ping.py b/yardstick/benchmark/scenarios/networking/ping.py index eb173f1df..d20814697 100644 --- a/yardstick/benchmark/scenarios/networking/ping.py +++ b/yardstick/benchmark/scenarios/networking/ping.py @@ -102,7 +102,7 @@ class Ping(base.Scenario): def _test(): # pragma: no cover - '''internal test function''' + """internal test function""" key_filename = pkg_resources.resource_filename("yardstick.resources", "files/yardstick_key") ctx = { diff --git a/yardstick/benchmark/scenarios/networking/ping6.py b/yardstick/benchmark/scenarios/networking/ping6.py index dd4272236..142a35664 100644 --- a/yardstick/benchmark/scenarios/networking/ping6.py +++ b/yardstick/benchmark/scenarios/networking/ping6.py @@ -84,7 +84,7 @@ class Ping6(base.Scenario): # pragma: no cover return None def setup(self): - '''scenario setup''' + """scenario setup""" self.setup_script = pkg_resources.resource_filename( 'yardstick.benchmark.scenarios.networking', Ping6.SETUP_SCRIPT) diff --git a/yardstick/benchmark/scenarios/networking/pktgen.py b/yardstick/benchmark/scenarios/networking/pktgen.py index 69663ec5f..b61337a70 100644 --- a/yardstick/benchmark/scenarios/networking/pktgen.py +++ b/yardstick/benchmark/scenarios/networking/pktgen.py @@ -47,7 +47,7 @@ class Pktgen(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.target_script = pkg_resources.resource_filename( 'yardstick.benchmark.scenarios.networking', Pktgen.TARGET_SCRIPT) @@ -148,7 +148,7 @@ class Pktgen(base.Scenario): def _test(): - '''internal test function''' + """internal test function""" key_filename = pkg_resources.resource_filename('yardstick.resources', 'files/yardstick_key') ctx = { diff --git a/yardstick/benchmark/scenarios/networking/pktgen_dpdk.py b/yardstick/benchmark/scenarios/networking/pktgen_dpdk.py index 2bdb91abb..0b70629f8 100644 --- a/yardstick/benchmark/scenarios/networking/pktgen_dpdk.py +++ b/yardstick/benchmark/scenarios/networking/pktgen_dpdk.py @@ -37,7 +37,7 @@ class PktgenDPDKLatency(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.pktgen_dpdk_script = pkg_resources.resource_filename( 'yardstick.benchmark.scenarios.networking', PktgenDPDKLatency.PKTGEN_DPDK_SCRIPT) diff --git a/yardstick/benchmark/scenarios/networking/sfc.py b/yardstick/benchmark/scenarios/networking/sfc.py index 87fea4f95..c558e3512 100644 --- a/yardstick/benchmark/scenarios/networking/sfc.py +++ b/yardstick/benchmark/scenarios/networking/sfc.py @@ -14,7 +14,7 @@ LOG = logging.getLogger(__name__) class Sfc(base.Scenario): # pragma: no cover - ''' SFC scenario class ''' + """ SFC scenario class """ __scenario_type__ = "sfc" @@ -31,7 +31,7 @@ class Sfc(base.Scenario): # pragma: no cover self.teardown_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.tacker_script = pkg_resources.resource_filename( 'yardstick.benchmark.scenarios.networking', Sfc.TACKER_SCRIPT) @@ -40,7 +40,7 @@ class Sfc(base.Scenario): # pragma: no cover 'yardstick.benchmark.scenarios.networking', Sfc.SERVER_SCRIPT) - ''' calling Tacker to instantiate VNFs and Service Chains ''' + """ calling Tacker to instantiate VNFs and Service Chains """ cmd_tacker = "%s" % (self.tacker_script) subprocess.call(cmd_tacker, shell=True) @@ -50,7 +50,7 @@ class Sfc(base.Scenario): # pragma: no cover target_pwd = target.get('password', 'opnfv') target_ip = target.get('ip', None) - ''' webserver start automatically during the vm boot ''' + """ webserver start automatically during the vm boot """ LOG.info("user:%s, target:%s", target_user, target_ip) self.server = ssh.SSH(target_user, target_ip, password=target_pwd, port=target_ssh_port) @@ -102,7 +102,7 @@ class Sfc(base.Scenario): # pragma: no cover self.setup_done = True def run(self, result): - ''' Creating client and server VMs to perform the test''' + """ Creating client and server VMs to perform the test""" host = self.context_cfg['host'] host_user = host.get('user', 'root') ssh_port = host.get("ssh_port", ssh.DEFAULT_PORT) @@ -149,7 +149,7 @@ class Sfc(base.Scenario): # pragma: no cover 'yardstick.benchmark.scenarios.networking', Sfc.TACKER_CHANGECLASSI) - ''' calling Tacker to change the classifier ''' + """ calling Tacker to change the classifier """ cmd_tacker = "%s" % (self.tacker_classi) subprocess.call(cmd_tacker, shell=True) @@ -185,7 +185,7 @@ class Sfc(base.Scenario): # pragma: no cover " :) \n" + '\033[0m') def teardown(self): - ''' for scenario teardown remove tacker VNFs, chains and classifiers''' + """ for scenario teardown remove tacker VNFs, chains and classifiers""" self.teardown_script = pkg_resources.resource_filename( "yardstick.benchmark.scenarios.networking", Sfc.TEARDOWN_SCRIPT) @@ -193,7 +193,7 @@ class Sfc(base.Scenario): # pragma: no cover self.teardown_done = True -'''def _test(): # pragma: no cover +"""def _test(): # pragma: no cover internal test function logger = logging.getLogger("Sfc Yardstick") @@ -208,4 +208,4 @@ class Sfc(base.Scenario): # pragma: no cover sfc.teardown() if __name__ == '__main__': # pragma: no cover - _test()''' + _test()""" diff --git a/yardstick/benchmark/scenarios/networking/vsperf.py b/yardstick/benchmark/scenarios/networking/vsperf.py index 9d6db7c1d..f2c2ea9b8 100644 --- a/yardstick/benchmark/scenarios/networking/vsperf.py +++ b/yardstick/benchmark/scenarios/networking/vsperf.py @@ -112,7 +112,7 @@ class Vsperf(base.Scenario): None) def setup(self): - '''scenario setup''' + """scenario setup""" vsperf = self.context_cfg['host'] vsperf_user = vsperf.get('user', 'ubuntu') vsperf_ssh_port = vsperf.get('ssh_port', ssh.DEFAULT_PORT) diff --git a/yardstick/benchmark/scenarios/networking/vtc_instantiation_validation.py b/yardstick/benchmark/scenarios/networking/vtc_instantiation_validation.py index bf42d9a9a..ac57c929c 100644 --- a/yardstick/benchmark/scenarios/networking/vtc_instantiation_validation.py +++ b/yardstick/benchmark/scenarios/networking/vtc_instantiation_validation.py @@ -29,7 +29,7 @@ class VtcInstantiationValidation(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.options = self.scenario_cfg['options'] self.setup_done = True diff --git a/yardstick/benchmark/scenarios/networking/vtc_instantiation_validation_noisy.py b/yardstick/benchmark/scenarios/networking/vtc_instantiation_validation_noisy.py index fb6e762d1..d3a9a9a02 100644 --- a/yardstick/benchmark/scenarios/networking/vtc_instantiation_validation_noisy.py +++ b/yardstick/benchmark/scenarios/networking/vtc_instantiation_validation_noisy.py @@ -29,7 +29,7 @@ class VtcInstantiationValidationNoisy(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.options = self.scenario_cfg['options'] self.setup_done = True diff --git a/yardstick/benchmark/scenarios/networking/vtc_throughput.py b/yardstick/benchmark/scenarios/networking/vtc_throughput.py index 0754d3782..b9cb0b1e7 100644 --- a/yardstick/benchmark/scenarios/networking/vtc_throughput.py +++ b/yardstick/benchmark/scenarios/networking/vtc_throughput.py @@ -29,7 +29,7 @@ class VtcThroughput(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.options = self.scenario_cfg['options'] self.setup_done = True diff --git a/yardstick/benchmark/scenarios/networking/vtc_throughput_noisy.py b/yardstick/benchmark/scenarios/networking/vtc_throughput_noisy.py index 552ef8090..38ebc4c42 100644 --- a/yardstick/benchmark/scenarios/networking/vtc_throughput_noisy.py +++ b/yardstick/benchmark/scenarios/networking/vtc_throughput_noisy.py @@ -29,7 +29,7 @@ class VtcThroughputNoisy(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.options = self.scenario_cfg['options'] self.setup_done = True diff --git a/yardstick/benchmark/scenarios/parser/parser.py b/yardstick/benchmark/scenarios/parser/parser.py index 6d39733c6..eb16833e5 100644 --- a/yardstick/benchmark/scenarios/parser/parser.py +++ b/yardstick/benchmark/scenarios/parser/parser.py @@ -68,7 +68,7 @@ class Parser(base.Scenario): result['yangtotosca'] = "success" if p.returncode == 0 else "fail" def teardown(self): - ''' for scenario teardown remove parser and pyang ''' + """ for scenario teardown remove parser and pyang """ self.teardown_script = pkg_resources.resource_filename( "yardstick.benchmark.scenarios.parser", Parser.TEARDOWN_SCRIPT) @@ -77,7 +77,7 @@ class Parser(base.Scenario): def _test(): - '''internal test function''' + """internal test function""" pass diff --git a/yardstick/benchmark/scenarios/storage/fio.py b/yardstick/benchmark/scenarios/storage/fio.py index 2a8738e88..e28bd7bcc 100644 --- a/yardstick/benchmark/scenarios/storage/fio.py +++ b/yardstick/benchmark/scenarios/storage/fio.py @@ -58,7 +58,7 @@ class Fio(base.Scenario): self.setup_done = False def setup(self): - '''scenario setup''' + """scenario setup""" self.target_script = pkg_resources.resource_filename( "yardstick.benchmark.scenarios.storage", Fio.TARGET_SCRIPT) @@ -152,7 +152,7 @@ class Fio(base.Scenario): def _test(): - '''internal test function''' + """internal test function""" key_filename = pkg_resources.resource_filename("yardstick.resources", "files/yardstick_key") ctx = { diff --git a/yardstick/cmd/__init__.py b/yardstick/cmd/__init__.py index 6b7d65792..3756d9ebb 100644 --- a/yardstick/cmd/__init__.py +++ b/yardstick/cmd/__init__.py @@ -10,7 +10,7 @@ from __future__ import print_function def print_hbar(barlen): - '''print to stdout a horizontal bar''' + """print to stdout a horizontal bar""" print(("+"), end=' ') print(("-" * barlen), end=' ') print("+") diff --git a/yardstick/cmd/cli.py b/yardstick/cmd/cli.py index 05bf8f06f..6281bb813 100644 --- a/yardstick/cmd/cli.py +++ b/yardstick/cmd/cli.py @@ -7,9 +7,9 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -''' +""" Command-line interface to yardstick -''' +""" from __future__ import absolute_import import logging @@ -57,7 +57,7 @@ def find_config_files(path_list): class YardstickCLI(): - '''Command-line interface to yardstick''' + """Command-line interface to yardstick""" # Command categories categories = { @@ -75,7 +75,7 @@ class YardstickCLI(): get_distribution('yardstick').version def _find_actions(self, subparsers, actions_module): - '''find action methods''' + """find action methods""" # Find action methods inside actions_module and # add them to the command parser. # The 'actions_module' argument may be a class @@ -94,7 +94,7 @@ class YardstickCLI(): subparser.set_defaults(func=callback) def _add_command_parsers(self, categories, subparsers): - '''add commands to command-line parser''' + """add commands to command-line parser""" for category in categories: command_object = categories[category]() desc = command_object.__doc__ or '' @@ -156,7 +156,7 @@ class YardstickCLI(): CONF.unregister_opts(self.opts) def main(self, argv): # pragma: no cover - '''run the command line interface''' + """run the command line interface""" try: self._register_cli_opt() @@ -169,7 +169,7 @@ class YardstickCLI(): self._clear_config_opts() def api(self, argv, task_id): # pragma: no cover - '''run the api interface''' + """run the api interface""" try: self._register_cli_opt() diff --git a/yardstick/cmd/commands/env.py b/yardstick/cmd/commands/env.py index dfcb63727..d5aef7faf 100644 --- a/yardstick/cmd/commands/env.py +++ b/yardstick/cmd/commands/env.py @@ -20,10 +20,10 @@ from yardstick.common.httpClient import HttpClient class EnvCommand(object): - ''' + """ Set of commands to prepare environment - ''' + """ def do_influxdb(self, args): data = {'action': 'createInfluxDBContainer'} diff --git a/yardstick/cmd/commands/plugin.py b/yardstick/cmd/commands/plugin.py index c3e951e8c..f97c490b7 100644 --- a/yardstick/cmd/commands/plugin.py +++ b/yardstick/cmd/commands/plugin.py @@ -18,21 +18,21 @@ from yardstick.cmd.commands import change_osloobj_to_paras class PluginCommands(object): - '''Plugin commands. + """Plugin commands. Set of commands to manage plugins. - ''' + """ @cliargs("input_file", type=str, help="path to plugin configuration file", nargs=1) def do_install(self, args): - '''Install a plugin.''' + """Install a plugin.""" param = change_osloobj_to_paras(args) Plugin().install(param) @cliargs("input_file", type=str, help="path to plugin configuration file", nargs=1) def do_remove(self, args): - '''Remove a plugin.''' + """Remove a plugin.""" param = change_osloobj_to_paras(args) Plugin().remove(param) diff --git a/yardstick/cmd/commands/runner.py b/yardstick/cmd/commands/runner.py index 02176aba3..b99ae789b 100644 --- a/yardstick/cmd/commands/runner.py +++ b/yardstick/cmd/commands/runner.py @@ -18,18 +18,18 @@ from yardstick.cmd.commands import change_osloobj_to_paras class RunnerCommands(object): - '''Runner commands. + """Runner commands. Set of commands to discover and display runner types. - ''' + """ def do_list(self, args): - '''List existing runner types''' + """List existing runner types""" param = change_osloobj_to_paras(args) Runners().list_all(param) @cliargs("type", type=str, help="runner type", nargs=1) def do_show(self, args): - '''Show details of a specific runner type''' + """Show details of a specific runner type""" param = change_osloobj_to_paras(args) Runners().show(param) diff --git a/yardstick/cmd/commands/scenario.py b/yardstick/cmd/commands/scenario.py index 5a6d04f55..618ed2915 100644 --- a/yardstick/cmd/commands/scenario.py +++ b/yardstick/cmd/commands/scenario.py @@ -17,18 +17,18 @@ from yardstick.cmd.commands import change_osloobj_to_paras class ScenarioCommands(object): - '''Scenario commands. + """Scenario commands. Set of commands to discover and display scenario types. - ''' + """ def do_list(self, args): - '''List existing scenario types''' + """List existing scenario types""" param = change_osloobj_to_paras(args) Scenarios().list_all(param) @cliargs("type", type=str, help="runner type", nargs=1) def do_show(self, args): - '''Show details of a specific scenario type''' + """Show details of a specific scenario type""" param = change_osloobj_to_paras(args) Scenarios().show(param) diff --git a/yardstick/cmd/commands/task.py b/yardstick/cmd/commands/task.py index fa82f078f..d7c0a01fb 100644 --- a/yardstick/cmd/commands/task.py +++ b/yardstick/cmd/commands/task.py @@ -19,10 +19,10 @@ output_file_default = "/tmp/yardstick.out" class TaskCommands(object): - '''Task commands. + """Task commands. Set of commands to manage benchmark tasks. - ''' + """ @cliargs("inputfile", type=str, help="path to task or suite file", nargs=1) @cliargs("--task-args", dest="task_args", @@ -42,4 +42,4 @@ class TaskCommands(object): action="store_true") def do_start(self, args, **kwargs): param = change_osloobj_to_paras(args) - Task().start(param) + Task().start(param, **kwargs) diff --git a/yardstick/cmd/commands/testcase.py b/yardstick/cmd/commands/testcase.py index 92831ad2f..bd17b1aa5 100644 --- a/yardstick/cmd/commands/testcase.py +++ b/yardstick/cmd/commands/testcase.py @@ -17,18 +17,18 @@ from yardstick.cmd.commands import change_osloobj_to_paras class TestcaseCommands(object): - '''Testcase commands. + """Testcase commands. Set of commands to discover and display test cases. - ''' + """ def do_list(self, args): - '''List existing test cases''' + """List existing test cases""" param = change_osloobj_to_paras(args) Testcase().list_all(param) @cliargs("casename", type=str, help="test case name", nargs=1) def do_show(self, args): - '''Show details of a specific test case''' + """Show details of a specific test case""" param = change_osloobj_to_paras(args) Testcase().show(param) diff --git a/yardstick/common/constants.py b/yardstick/common/constants.py index d99e216f4..ffca4b3e9 100644 --- a/yardstick/common/constants.py +++ b/yardstick/common/constants.py @@ -55,3 +55,5 @@ OPENSTACK_RC_FILE = join(YARDSTICK_CONFIG_DIR, 'openstack.creds') BASE_URL = 'http://localhost:5000' ENV_ACTION_API = BASE_URL + '/yardstick/env/action' ASYNC_TASK_API = BASE_URL + '/yardstick/asynctask' + +SQLITE = 'sqlite:////tmp/yardstick.db' diff --git a/yardstick/common/template_format.py b/yardstick/common/template_format.py index 2432c5dc6..e1662ced1 100644 --- a/yardstick/common/template_format.py +++ b/yardstick/common/template_format.py @@ -42,11 +42,11 @@ yaml_loader.add_constructor(u'tag:yaml.org,2002:timestamp', def parse(tmpl_str): - '''Takes a string and returns a dict containing the parsed structure. + """Takes a string and returns a dict containing the parsed structure. This includes determination of whether the string is using the JSON or YAML format. - ''' + """ if tmpl_str.startswith('{'): tpl = jsonutils.loads(tmpl_str) else: diff --git a/yardstick/dispatcher/base.py b/yardstick/dispatcher/base.py index 6e863cadc..09ce8d1e8 100644 --- a/yardstick/dispatcher/base.py +++ b/yardstick/dispatcher/base.py @@ -31,7 +31,7 @@ class Base(object): @staticmethod def get_cls(dispatcher_type): - '''Return class of specified type.''' + """Return class of specified type.""" for dispatcher in utils.itersubclasses(Base): if dispatcher_type == dispatcher.__dispatcher_type__: return dispatcher diff --git a/yardstick/main.py b/yardstick/main.py index 5d427beb8..5fc0c2e17 100755 --- a/yardstick/main.py +++ b/yardstick/main.py @@ -45,7 +45,7 @@ from yardstick.cmd.cli import YardstickCLI def main(): - '''yardstick main''' + """yardstick main""" YardstickCLI().main(sys.argv[1:]) if __name__ == '__main__': diff --git a/yardstick/network_services/__init__.py b/yardstick/network_services/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/yardstick/network_services/__init__.py diff --git a/yardstick/network_services/collector/__init__.py b/yardstick/network_services/collector/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/yardstick/network_services/collector/__init__.py diff --git a/yardstick/network_services/collector/publisher.py b/yardstick/network_services/collector/publisher.py new file mode 100644 index 000000000..004d4774b --- /dev/null +++ b/yardstick/network_services/collector/publisher.py @@ -0,0 +1,29 @@ +# Copyright (c) 2016-2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""This module implements stub for publishing results in yardstick format.""" + + +class Publisher(object): + """Class that handles publishing test results in yardstick format.""" + + def __init__(self): + super(Publisher, self).__init__() + + def start(self): + """Nothing to do, yet""" + pass + + def stop(self): + """Nothing to do, yet""" + pass diff --git a/yardstick/network_services/collector/subscriber.py b/yardstick/network_services/collector/subscriber.py new file mode 100644 index 000000000..3bcb20876 --- /dev/null +++ b/yardstick/network_services/collector/subscriber.py @@ -0,0 +1,39 @@ +# Copyright (c) 2016-2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""This module implements stub for publishing results in yardstick format.""" + + +class Collector(object): + """Class that handles dictionary of results in yardstick-plot format.""" + + def __init__(self, traffic_profile, vnfs): + super(Collector, self).__init__() + self.traffic_profile = traffic_profile + self.service = vnfs + + def start(self): + """Nothing to do, yet""" + pass + + def stop(self): + """Nothing to do, yet""" + pass + + @classmethod + def get_kpi(cls, vnf): + """Returns dictionary of results in yardstick-plot format + + :return: + """ + return {vnf.name: vnf.collect_kpi()} diff --git a/yardstick/orchestrator/heat.py b/yardstick/orchestrator/heat.py index 7e0f360c4..c098de9e3 100644 --- a/yardstick/orchestrator/heat.py +++ b/yardstick/orchestrator/heat.py @@ -38,14 +38,14 @@ def get_short_key_uuid(uuid): class HeatObject(object): - ''' base class for template and stack''' + """ base class for template and stack""" def __init__(self): self._heat_client = None self.uuid = None def _get_heat_client(self): - '''returns a heat client instance''' + """returns a heat client instance""" if self._heat_client is None: sess = op_utils.get_session() @@ -57,14 +57,14 @@ class HeatObject(object): return self._heat_client def status(self): - '''returns stack state as a string''' + """returns stack state as a string""" heat = self._get_heat_client() stack = heat.stacks.get(self.uuid) return getattr(stack, 'stack_status') class HeatStack(HeatObject): - ''' Represents a Heat stack (deployed template) ''' + """ Represents a Heat stack (deployed template) """ stacks = [] def __init__(self, name): @@ -76,11 +76,11 @@ class HeatStack(HeatObject): @staticmethod def stacks_exist(): - '''check if any stack has been deployed''' + """check if any stack has been deployed""" return len(HeatStack.stacks) > 0 def _delete(self): - '''deletes a stack from the target cloud using heat''' + """deletes a stack from the target cloud using heat""" if self.uuid is None: return @@ -106,10 +106,10 @@ class HeatStack(HeatObject): self.uuid = None def delete(self, block=True, retries=3): - '''deletes a stack in the target cloud using heat (with retry) + """deletes a stack in the target cloud using heat (with retry) Sometimes delete fail with "InternalServerError" and the next attempt succeeds. So it is worthwhile to test a couple of times. - ''' + """ if self.uuid is None: return @@ -139,12 +139,12 @@ class HeatStack(HeatObject): stack.delete() def update(self): - '''update a stack''' + """update a stack""" raise RuntimeError("not implemented") class HeatTemplate(HeatObject): - '''Describes a Heat template and a method to deploy template to a stack''' + """Describes a Heat template and a method to deploy template to a stack""" def _init_template(self): self._template = {} @@ -152,9 +152,9 @@ class HeatTemplate(HeatObject): timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") self._template['description'] = \ - '''Stack built by the yardstick framework for %s on host %s %s. + """Stack built by the yardstick framework for %s on host %s %s. All referred generated resources are prefixed with the template - name (i.e. %s).''' % (getpass.getuser(), socket.gethostname(), + name (i.e. %s).""" % (getpass.getuser(), socket.gethostname(), timestamp, self.name) # short hand for resources part of template @@ -190,7 +190,7 @@ class HeatTemplate(HeatObject): log.debug("template object '%s' created", name) def add_network(self, name): - '''add to the template a Neutron Net''' + """add to the template a Neutron Net""" log.debug("adding Neutron::Net '%s'", name) self.resources[name] = { 'type': 'OS::Neutron::Net', @@ -198,7 +198,7 @@ class HeatTemplate(HeatObject): } def add_subnet(self, name, network, cidr): - '''add to the template a Neutron Subnet''' + """add to the template a Neutron Subnet""" log.debug("adding Neutron::Subnet '%s' in network '%s', cidr '%s'", name, network, cidr) self.resources[name] = { @@ -217,7 +217,7 @@ class HeatTemplate(HeatObject): } def add_router(self, name, ext_gw_net, subnet_name): - '''add to the template a Neutron Router and interface''' + """add to the template a Neutron Router and interface""" log.debug("adding Neutron::Router:'%s', gw-net:'%s'", name, ext_gw_net) self.resources[name] = { @@ -232,7 +232,7 @@ class HeatTemplate(HeatObject): } def add_router_interface(self, name, router_name, subnet_name): - '''add to the template a Neutron RouterInterface and interface''' + """add to the template a Neutron RouterInterface and interface""" log.debug("adding Neutron::RouterInterface '%s' router:'%s', " "subnet:'%s'", name, router_name, subnet_name) @@ -246,7 +246,7 @@ class HeatTemplate(HeatObject): } def add_port(self, name, network_name, subnet_name, sec_group_id=None): - '''add to the template a named Neutron Port''' + """add to the template a named Neutron Port""" log.debug("adding Neutron::Port '%s', network:'%s', subnet:'%s', " "secgroup:%s", name, network_name, subnet_name, sec_group_id) self.resources[name] = { @@ -272,9 +272,9 @@ class HeatTemplate(HeatObject): def add_floating_ip(self, name, network_name, port_name, router_if_name, secgroup_name=None): - '''add to the template a Nova FloatingIP resource + """add to the template a Nova FloatingIP resource see: https://bugs.launchpad.net/heat/+bug/1299259 - ''' + """ log.debug("adding Nova::FloatingIP '%s', network '%s', port '%s', " "rif '%s'", name, network_name, port_name, router_if_name) @@ -295,8 +295,8 @@ class HeatTemplate(HeatObject): } def add_floating_ip_association(self, name, floating_ip_name, port_name): - '''add to the template a Nova FloatingIP Association resource - ''' + """add to the template a Nova FloatingIP Association resource + """ log.debug("adding Nova::FloatingIPAssociation '%s', server '%s', " "floating_ip '%s'", name, port_name, floating_ip_name) @@ -310,7 +310,7 @@ class HeatTemplate(HeatObject): } def add_keypair(self, name, key_uuid): - '''add to the template a Nova KeyPair''' + """add to the template a Nova KeyPair""" log.debug("adding Nova::KeyPair '%s'", name) self.resources[name] = { 'type': 'OS::Nova::KeyPair', @@ -327,7 +327,7 @@ class HeatTemplate(HeatObject): } def add_servergroup(self, name, policy): - '''add to the template a Nova ServerGroup''' + """add to the template a Nova ServerGroup""" log.debug("adding Nova::ServerGroup '%s', policy '%s'", name, policy) if policy not in ["anti-affinity", "affinity"]: raise ValueError(policy) @@ -346,7 +346,7 @@ class HeatTemplate(HeatObject): } def add_security_group(self, name): - '''add to the template a Neutron SecurityGroup''' + """add to the template a Neutron SecurityGroup""" log.debug("adding Neutron::SecurityGroup '%s'", name) self.resources[name] = { 'type': 'OS::Neutron::SecurityGroup', @@ -376,7 +376,7 @@ class HeatTemplate(HeatObject): def add_server(self, name, image, flavor, ports=None, networks=None, scheduler_hints=None, user=None, key_name=None, user_data=None, metadata=None, additional_properties=None): - '''add to the template a Nova Server''' + """add to the template a Nova Server""" log.debug("adding Nova::Server '%s', image '%s', flavor '%s', " "ports %s", name, image, flavor, ports) @@ -435,8 +435,8 @@ class HeatTemplate(HeatObject): } def create(self, block=True): - '''creates a template in the target cloud using heat - returns a dict with the requested output values from the template''' + """creates a template in the target cloud using heat + returns a dict with the requested output values from the template""" log.info("Creating stack '%s'", self.name) # create stack early to support cleanup, e.g. ctrl-c while waiting diff --git a/yardstick/plot/plotter.py b/yardstick/plot/plotter.py index 4e65303dc..2f1f25228 100644 --- a/yardstick/plot/plotter.py +++ b/yardstick/plot/plotter.py @@ -9,12 +9,12 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -''' yardstick-plot - a command line tool for visualizing results from the +""" yardstick-plot - a command line tool for visualizing results from the output file of yardstick framework. Example invocation: $ yardstick-plot -i /tmp/yardstick.out -o /tmp/plots/ -''' +""" from __future__ import absolute_import from __future__ import print_function @@ -32,7 +32,7 @@ from six.moves import zip class Parser(object): - ''' Command-line argument and input file parser for yardstick-plot tool''' + """ Command-line argument and input file parser for yardstick-plot tool""" def __init__(self): self.data = { @@ -45,7 +45,7 @@ class Parser(object): self.scenarios = {} def _get_parser(self): - '''get a command-line parser''' + """get a command-line parser""" parser = argparse.ArgumentParser( prog='yardstick-plot', description="A tool for visualizing results from yardstick. " @@ -65,7 +65,7 @@ class Parser(object): return parser def _add_record(self, record): - '''add record to the relevant scenario''' + """add record to the relevant scenario""" if "runner_id" in record and "benchmark" not in record: obj_name = record["scenario_cfg"]["runner"]["object"] self.scenarios[record["runner_id"]] = obj_name @@ -76,13 +76,13 @@ class Parser(object): self.data[test_type].append(record) def parse_args(self): - '''parse command-line arguments''' + """parse command-line arguments""" parser = self._get_parser() self.args = parser.parse_args() return self.args def parse_input_file(self): - '''parse the input test results file''' + """parse the input test results file""" if self.args.input: input_file = self.args.input else: @@ -101,7 +101,7 @@ class Parser(object): class Plotter(object): - '''Graph plotter for scenario-specific results from yardstick framework''' + """Graph plotter for scenario-specific results from yardstick framework""" def __init__(self, data, output_folder): self.data = data @@ -110,7 +110,7 @@ class Plotter(object): self.colors = ['g', 'b', 'c', 'm', 'y'] def plot(self): - '''plot the graph(s)''' + """plot the graph(s)""" for test_type in self.data.keys(): if self.data[test_type]: plt.figure(self.fig_counter) @@ -122,7 +122,7 @@ class Plotter(object): self._save_plot(test_type) def _save_plot(self, test_type): - '''save the graph to output folder''' + """save the graph to output folder""" timestr = time.strftime("%Y%m%d-%H%M%S") file_name = test_type + "_" + timestr + ".png" if not self.output_folder: @@ -135,7 +135,7 @@ class Plotter(object): print(("Saved graph to " + new_file)) def _plot_ping(self, records): - '''ping test result interpretation and visualization on the graph''' + """ping test result interpretation and visualization on the graph""" rtts = [r['benchmark']['data']['rtt'] for r in records] seqs = [r['benchmark']['sequence'] for r in records] @@ -157,7 +157,7 @@ class Plotter(object): plt.ylabel("round trip time in milliseconds (rtt)") def _plot_pktgen(self, records): - '''pktgen test result interpretation and visualization on the graph''' + """pktgen test result interpretation and visualization on the graph""" flows = [r['benchmark']['data']['flows'] for r in records] sent = [r['benchmark']['data']['packets_sent'] for r in records] received = [int(r['benchmark']['data']['packets_received']) @@ -183,7 +183,7 @@ class Plotter(object): plt.ylabel("lost packets per million packets (ppm)") def _plot_iperf3(self, records): - '''iperf3 test result interpretation and visualization on the graph''' + """iperf3 test result interpretation and visualization on the graph""" intervals = [] for r in records: # If did not fail the SLA @@ -213,7 +213,7 @@ class Plotter(object): plt.ylabel("bandwidth in Kb/s") def _plot_fio(self, records): - '''fio test result interpretation and visualization on the graph''' + """fio test result interpretation and visualization on the graph""" rw_types = [r['sargs']['options']['rw'] for r in records] seqs = [x for x in range(1, len(records) + 1)] data = {} @@ -277,8 +277,8 @@ class Plotter(object): plt.xticks(seqs, seqs) def _plot_fio_helper(self, data, seqs, key, bar_color, axl): - '''check if measurements exist for a key and then plot the - data to a given subplot''' + """check if measurements exist for a key and then plot the + data to a given subplot""" if key in data: if len(data[key]) == 1: axl.bar(0.1, data[key], 0.35, color=bar_color) @@ -287,7 +287,7 @@ class Plotter(object): axl.plot(seqs, data[key], line_style) def _construct_legend(self, legend_texts, obj=plt): - '''construct legend for the plot or subplot''' + """construct legend for the plot or subplot""" ci = 0 lines = [] diff --git a/yardstick/ssh.py b/yardstick/ssh.py index 1cad8eefa..cfbc3ca96 100644 --- a/yardstick/ssh.py +++ b/yardstick/ssh.py @@ -202,7 +202,7 @@ class SSH(object): start_time = time.time() # encode on transmit, decode on receive - data_to_send = encodeutils.safe_encode("") + data_to_send = encodeutils.safe_encode("", incoming='utf-8') stderr_data = None # If we have data to be sent to stdin then `select' should also @@ -234,8 +234,11 @@ class SSH(object): if session.send_ready(): if stdin is not None and not stdin.closed: if not data_to_send: + stdin_txt = stdin.read(4096) + if stdin_txt is None: + stdin_txt = '' data_to_send = encodeutils.safe_encode( - stdin.read(4096), incoming='utf-8') + stdin_txt, incoming='utf-8') if not data_to_send: # we may need to keep stdin open if not keep_stdin_open: diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarking_unit.py b/yardstick/vTC/apexlake/experimental_framework/benchmarking_unit.py index d5de308c7..56ea6d2f0 100644 --- a/yardstick/vTC/apexlake/experimental_framework/benchmarking_unit.py +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarking_unit.py @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -''' +""" The Benchmarking Unit manages the Benchmarking of VNFs orchestrating the initialization, execution and finalization -''' +""" from __future__ import absolute_import diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarks/benchmark_base_class.py b/yardstick/vTC/apexlake/experimental_framework/benchmarks/benchmark_base_class.py index 96cce2265..38c91ee3a 100644 --- a/yardstick/vTC/apexlake/experimental_framework/benchmarks/benchmark_base_class.py +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarks/benchmark_base_class.py @@ -18,11 +18,11 @@ import abc class BenchmarkBaseClass(object): - ''' + """ This class represents a Benchmark that we want to run on the platform. One of them will be the calculation of the throughput changing the configuration parameters - ''' + """ def __init__(self, name, params): if not params: diff --git a/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py b/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py index 0f0af8b05..1904af20b 100644 --- a/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py +++ b/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py @@ -13,9 +13,9 @@ # limitations under the License. -''' +""" Generation of the heat templates from the base template -''' +""" from __future__ import absolute_import import json diff --git a/yardstick/vTC/apexlake/experimental_framework/libraries/__init__.py b/yardstick/vTC/apexlake/experimental_framework/libraries/__init__.py index dcc18a45b..876e3ca31 100644 --- a/yardstick/vTC/apexlake/experimental_framework/libraries/__init__.py +++ b/yardstick/vTC/apexlake/experimental_framework/libraries/__init__.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -''' +""" Libraries to be used by the framework. -''' +""" __author__ = 'vmriccox' diff --git a/yardstick/vTC/apexlake/experimental_framework/packet_generators/__init__.py b/yardstick/vTC/apexlake/experimental_framework/packet_generators/__init__.py index a7c96a842..935f144f4 100644 --- a/yardstick/vTC/apexlake/experimental_framework/packet_generators/__init__.py +++ b/yardstick/vTC/apexlake/experimental_framework/packet_generators/__init__.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -''' +""" Packet generators -''' +""" __author__ = 'vmriccox' diff --git a/yardstick/vTC/apexlake/experimental_framework/packet_generators/dpdk_packet_generator.py b/yardstick/vTC/apexlake/experimental_framework/packet_generators/dpdk_packet_generator.py index 959003628..bd81527a2 100644 --- a/yardstick/vTC/apexlake/experimental_framework/packet_generators/dpdk_packet_generator.py +++ b/yardstick/vTC/apexlake/experimental_framework/packet_generators/dpdk_packet_generator.py @@ -34,10 +34,10 @@ class DpdkPacketGenerator(base_packet_generator.BasePacketGenerator): self.dpdk_interfaces = -1 def send_traffic(self): - ''' + """ Calls the packet generator and starts to send traffic Blocking call - ''' + """ current_dir = os.path.dirname(os.path.realpath(__file__)) DpdkPacketGenerator._chdir(self.directory) dpdk_vars = common.get_dpdk_pktgen_vars() diff --git a/yardstick/vTC/apexlake/tests/dpdk_packet_generator_test.py b/yardstick/vTC/apexlake/tests/dpdk_packet_generator_test.py index 0b0df6c2b..96ead5ef7 100644 --- a/yardstick/vTC/apexlake/tests/dpdk_packet_generator_test.py +++ b/yardstick/vTC/apexlake/tests/dpdk_packet_generator_test.py @@ -288,10 +288,10 @@ class TestDpdkPacketGenSendTraffic(unittest.TestCase): mock_dir_name, mock_os_path, mock_os_system): - ''' + """ Calls the packet generator and starts to send traffic Blocking call - ''' + """ mock_get_core_nics.return_value = "{corenics}" mock_os_path.realpath.return_value = 'pktgen_dir_test' mock_os_path.dirname.return_value = 'current_directory' |