diff options
81 files changed, 1336 insertions, 306 deletions
diff --git a/api/client.py b/api/client.py new file mode 100644 index 000000000..167754c39 --- /dev/null +++ b/api/client.py @@ -0,0 +1,37 @@ +############################################################################## +# Copyright (c) 2016 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +import logging +import requests + +from oslo_serialization import jsonutils + +from yardstick.common import constants as consts + +logger = logging.getLogger(__name__) + + +def post(url, data={}): + url = '{}{}'.format(consts.BASE_URL, url) + data = jsonutils.dumps(data) + headers = {'Content-Type': 'application/json'} + try: + response = requests.post(url, data=data, headers=headers) + result = response.json() + logger.debug('The result is: %s', result) + + return result + except Exception as e: + logger.exception('Failed: %s', e) + raise + + +def get(url): + url = '{}{}'.format(consts.BASE_URL, url) + response = requests.get(url) + return response.json() 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/resources/testcases.py b/api/resources/testcases.py new file mode 100644 index 000000000..6ee15efb3 --- /dev/null +++ b/api/resources/testcases.py @@ -0,0 +1,21 @@ +# ############################################################################ +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +# ############################################################################ +from yardstick.benchmark.core.testcase import Testcase +from yardstick.benchmark.core import Param +from api.utils import common as common_utils + + +def default(args): + return listAllTestcases(args) + + +def listAllTestcases(args): + param = Param(args) + testcase_list = Testcase().list_all(param) + return common_utils.result_handler(1, testcase_list) 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/api/urls.py b/api/urls.py index 04b7485f1..3ccb67dbc 100644 --- a/api/urls.py +++ b/api/urls.py @@ -13,6 +13,7 @@ from api.utils.common import Url urlpatterns = [ Url('/yardstick/asynctask', views.Asynctask, 'asynctask'), + Url('/yardstick/testcases', views.Testcases, 'testcases'), Url('/yardstick/testcases/release/action', views.ReleaseAction, 'release'), Url('/yardstick/testcases/samples/action', views.SamplesAction, 'samples'), Url('/yardstick/testsuites/action', views.TestsuitesAction, 'testsuites'), diff --git a/api/views.py b/api/views.py index 0c39bfad0..9fd236fad 100644 --- a/api/views.py +++ b/api/views.py @@ -30,6 +30,11 @@ class Asynctask(ApiResource): return self._dispatch_get() +class Testcases(ApiResource): + def get(self): + return self._dispatch_get() + + class ReleaseAction(ApiResource): @swag_from(os.getcwd() + '/swagger/docs/release_action.yaml') def post(self): diff --git a/requirements.txt b/requirements.txt index 8f03c8717..107e8dee4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,7 +53,7 @@ pycrypto==2.6.1 pyflakes==1.0.0 pyparsing==2.1.0 pyrsistent==0.11.12 -osc-lib==1.3.0 +osc-lib==1.2.0 python-cinderclient==1.9.0 python-glanceclient==2.5.0 python-heatclient==1.5.0 diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml index aa2980f69..ceec6cf5e 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc001.yaml @@ -1,11 +1,11 @@ --- -# Yardstick TC001 config file -# Measure network throughput using pktgen -# Different amounts of flows are tested with, from 2 up to 1001000 -# All tests are run twice. First twice with the least amount of -#ports and further on. schema: "yardstick:task:0.1" +description: > + Yardstick TC001 config file; + Measure network throughput using pktgen; + Different amounts of flows are tested with, from 2 up to 1001000; + All tests are run twice. First twice with the least amount of ports and further on. scenarios: {% for num_ports in [1, 10, 50, 100, 500, 1000] %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc002.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc002.yaml index 3c7b988c0..6830dcd72 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc002.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc002.yaml @@ -1,7 +1,10 @@ --- -# measure network latency using ping schema: "yardstick:task:0.1" +description: > + Yardstick TC002 config file; + measure network latency using ping; + {% set image = image or "cirros-0.3.3" %} scenarios: {% for i in range(2) %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml index f5a2778e8..82e85dbd1 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc005.yaml @@ -1,8 +1,10 @@ --- -# Yardstick TC005 config file -# Measure Storage IOPS, throughput and latency using fio schema: "yardstick:task:0.1" +description: > + Yardstick TC005 config file; + Measure Storage IOPS, throughput and latency using fio. + scenarios: {% for rw in ['read', 'write', 'randwrite', 'randread', 'rw'] %} {% for bs in ['4k', '64k', '1024k'] %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml index 7221518ab..5dfb29b97 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc006.yaml @@ -1,5 +1,8 @@ --- + schema: "yardstick:task:0.1" +description: > + Yardstick TC006 config file. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml index 6f99ea6f2..882b3cf9c 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc007.yaml @@ -1,8 +1,9 @@ --- -# Sample benchmark task config file -# vTC schema: "yardstick:task:0.1" +description: > + Sample benchmark task config file; + vTC. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml index a2f5f3adc..89986f7f1 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc008.yaml @@ -1,15 +1,16 @@ --- -# Yardstick TC008 config file -# Measure network throughput and packet loss using Pktgen. -# Different amount of flows, from 2 up to 1001000, in combination -# with different packet sizes are run in each test. -# Each combination of packet size and flow amount is run 10 times. -# First 10 times with the smallest packet size, starting with the -# least amount of ports/flows, then next amount of ports with same -# packet size, and so on. The test sequence continues with the next -# packet size, with same ports/flows sequence as before. schema: "yardstick:task:0.1" +description: > + Yardstick TC008 config file; + Measure network throughput and packet loss using Pktgen; + Different amount of flows, from 2 up to 1001000, in combination + with different packet sizes are run in each test. + Each combination of packet size and flow amount is run 10 times. + First 10 times with the smallest packet size, starting with the + least amount of ports/flows, then next amount of ports with same + packet size, and so on. The test sequence continues with the next + packet size, with same ports/flows sequence as before. scenarios: {% for pkt_size in [64, 128, 256, 512, 1024, 1280, 1518] %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml index f9fa1b778..e18ca789d 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc009.yaml @@ -1,12 +1,13 @@ --- -# Yardstick TC009 config file -# Measure network throughput and packet loss using pktgen. -# Different amounts of flows are tested with, from 2 up to 1001000. -# All tests are run 10 times each. First 10 times with the least -# amount of ports, then 10 times with the next amount of ports, -# and so on until all packet sizes have been run with. schema: "yardstick:task:0.1" +description: > + Yardstick TC009 config file; + Measure network throughput and packet loss using pktgen; + Different amounts of flows are tested with, from 2 up to 1001000; + All tests are run 10 times each. First 10 times with the least + amount of ports, then 10 times with the next amount of ports, + and so on until all packet sizes have been run with; scenarios: {% for num_ports in [1, 10, 50, 100, 500, 1000] %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml index 6c7f96799..ad344e58f 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc010.yaml @@ -1,8 +1,9 @@ --- -# Yardstick TC010 config file -# measure memory read latency using lmbench schema: "yardstick:task:0.1" +description: > + Yardstick TC010 config file; + measure memory read latency using lmbench. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml index 4cd3119bb..5ff31ea9b 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc011.yaml @@ -1,8 +1,9 @@ --- -# Yardstick TC011 config file -# Measure packet delay variation (jitter) using iperf3 schema: "yardstick:task:0.1" +description: > + Yardstick TC011 config file; + Measure packet delay variation (jitter) using iperf3. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml index ba246ff11..805f627c0 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc012.yaml @@ -1,8 +1,9 @@ --- -# Yardstick TC012 config file -# Measure memory read and write bandwidth using lmbench schema: "yardstick:task:0.1" +description: > + Yardstick TC012 config file; + Measure memory read and write bandwidth using lmbench. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml index 1ac0f2961..fc1446206 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc014.yaml @@ -1,8 +1,9 @@ --- -# Yardstick TC014 config file -# Measure Processing speed using unixbench schema: "yardstick:task:0.1" +description: > + Yardstick TC014 config file; + Measure Processing speed using unixbench. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc019.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc019.yaml index 2e5a4a56f..b49019633 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc019.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc019.yaml @@ -1,7 +1,8 @@ --- -# Sample test case for the HA of controller node Openstack service schema: "yardstick:task:0.1" +description: > + Sample test case for the HA of controller node Openstack service. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml index cbdaf3970..3bcabaac6 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc020.yaml @@ -1,5 +1,8 @@ --- + schema: "yardstick:task:0.1" +description: > + Yardstick TC020 config file. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml index 17249785a..263663ebe 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc021.yaml @@ -1,5 +1,8 @@ --- + schema: "yardstick:task:0.1" +description: > + Yardstick TC021 config file. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc025.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc025.yaml index b083f6f20..0bbc5b8a6 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc025.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc025.yaml @@ -1,7 +1,8 @@ --- -# Sample test case for the HA of OpenStack Controll Node abnormally shutdown schema: "yardstick:task:0.1" +description: > + Sample test case for the HA of OpenStack Controll Node abnormally shutdown. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc027.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc027.yaml index 5032f3de3..036b6e9fd 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc027.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc027.yaml @@ -1,8 +1,10 @@ --- -# Yardstick TC027 config file -# Measure IPV6 network latency using ping6 schema: "yardstick:task:0.1" +description: > + Yardstick TC027 config file; + Measure IPV6 network latency using ping6. + {% set openrc = openrc or "/opt/admin-openrc.sh" %} {% set external_network = external_network or "ext-net" %} {% set pod_info = pod_info or "etc/yardstick/nodes/compass_sclab_physical/pod.yaml" %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml index cd42098d2..0db490a15 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml @@ -1,15 +1,15 @@ --- -# Yardstick TC037 config file -# Measure network throughput and packet loss using pktgen. -# Different amounts of flows are tested with, from 2 up to 1001000. -# All tests are run 2 times each. First 2 times with the least -# amount of ports, then 2 times with the next amount of ports, -# and so on until all packet sizes have been run with. -# -# During the measurements system load and network latency are -# recorded/measured using ping and mpstat, respectively. schema: "yardstick:task:0.1" +description: > + Yardstick TC037 config file; + Measure network throughput and packet loss using pktgen; + Different amounts of flows are tested with, from 2 up to 1001000; + All tests are run 2 times each. First 2 times with the least + amount of ports, then 2 times with the next amount of ports, + and so on until all packet sizes have been run with; + During the measurements system load and network latency are + recorded/measured using ping and mpstat, respectively; scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml index c2e5b4028..e6ba0c1a4 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc038.yaml @@ -1,15 +1,15 @@ --- -# Yardstick TC038 config file -# Measure network throughput and packet loss using pktgen. -# Different amounts of flows are tested with, from 2 up to 1001000. -# All tests are run 10 times each. First 10 times with the least -# amount of ports, then 10 times with the next amount of ports, -# and so on until all packet sizes have been run with. -# -# During the measurements system load and network latency are -# recorded/measured using ping and mpstat, respectively. schema: "yardstick:task:0.1" +description: > + Yardstick TC038 config file; + Measure network throughput and packet loss using pktgen; + Different amounts of flows are tested with, from 2 up to 1001000; + All tests are run 10 times each. First 10 times with the least + amount of ports, then 10 times with the next amount of ports, + and so on until all packet sizes have been run with; + During the measurements system load and network latency are + recorded/measured using ping and mpstat, respectively; scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc040.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc040.yaml index 0a6dee656..c6094678e 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc040.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc040.yaml @@ -1,8 +1,9 @@ --- -# Yardstick TC040 config file -# Running Parser Yang-to-Tosca module as a tool, validating output against expected outcome schema: "yardstick:task:0.1" +description: > + Yardstick TC040 config file; + Running Parser Yang-to-Tosca module as a tool, validating output against expected outcome. scenarios: diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc042.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc042.yaml index 158f5076e..c233acb2f 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc042.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc042.yaml @@ -1,8 +1,9 @@ --- -# Yardstick TC042 config file -# Measure network latency using testpmd and pktgen-dpdk schema: "yardstick:task:0.1" +description: > + Yardstick TC042 config file; + Measure network latency using testpmd and pktgen-dpdk. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml index d5754b966..2546b6209 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml @@ -1,8 +1,10 @@ --- -# Yardstick TC043 config file -# Measure latency between NFVI nodes using ping schema: "yardstick:task:0.1" +description: > + Yardstick TC043 config file; + Measure latency between NFVI nodes using ping. + {% set host = host or "node1.LF" %} {% set target = target or "node2.LF" %} {% set pod_info = pod_info or "etc/yardstick/nodes/compass_sclab_physical/pod.yaml" %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc045.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc045.yaml index 79ad61e86..196994544 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc045.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc045.yaml @@ -1,7 +1,8 @@ --- -# Test case for TC045 :Control node Openstack service down - neutron server schema: "yardstick:task:0.1" +description: > + Test case for TC045 :Control node Openstack service down - neutron server. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc046.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc046.yaml index 69cef40a8..1af561964 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc046.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc046.yaml @@ -1,7 +1,8 @@ --- -# Test case for TC046 :Control node Openstack service down - keystone schema: "yardstick:task:0.1" +description: > + Test case for TC046 :Control node Openstack service down - keystone. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc047.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc047.yaml index f6019f6d5..24c28f5de 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc047.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc047.yaml @@ -1,7 +1,8 @@ --- -# Test case for TC047 :Control node Openstack service down - glance api schema: "yardstick:task:0.1" +description: > + Test case for TC047 :Control node Openstack service down - glance api. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc048.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc048.yaml index 543db9780..190084db9 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc048.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc048.yaml @@ -1,7 +1,8 @@ --- -# Test case for TC048 :Control node Openstack service down - cinder api schema: "yardstick:task:0.1" +description: > + Test case for TC048 :Control node Openstack service down - cinder api. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc049.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc049.yaml index 759867d46..66c154117 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc049.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc049.yaml @@ -1,7 +1,8 @@ --- -# Test case for TC049 :Control node Openstack service down - swift proxy schema: "yardstick:task:0.1" +description: > + Test case for TC049 :Control node Openstack service down - swift proxy. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc050.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc050.yaml index 0b21f8861..a8cb920ea 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc050.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc050.yaml @@ -1,8 +1,10 @@ --- -# Test case for TC050 :OpenStack Controller Node Network High Availability -# This test case is written by new scenario-based HA testing framework schema: "yardstick:task:0.1" +description: > + Test case for TC050 :OpenStack Controller Node Network High Availability; + This test case is written by new scenario-based HA testing framework. + scenarios: - type: "GeneralHA" diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc051.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc051.yaml index 8e2e0c789..1115b35f6 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc051.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc051.yaml @@ -1,8 +1,10 @@ --- -# Test case for TC051 :OpenStack Controller Node CPU Overload High Availability -# This test case is written by new scenario-based HA testing framework schema: "yardstick:task:0.1" +description: > + Test case for TC051 :OpenStack Controller Node CPU Overload High Availability; + This test case is written by new scenario-based HA testing framework. + scenarios: - type: "GeneralHA" diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc052.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc052.yaml index 714306881..67619d3d0 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc052.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc052.yaml @@ -1,8 +1,10 @@ --- -# Test case for TC052 :OpenStack Controller Node Disk I/O Block High Availability -# This test case is written by new scenario-based HA testing framework schema: "yardstick:task:0.1" +description: > + Test case for TC052 :OpenStack Controller Node Disk I/O Block High Availability; + This test case is written by new scenario-based HA testing framework. + scenarios: - type: "GeneralHA" diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc053.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc053.yaml index 696ed3ba4..16a971124 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc053.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc053.yaml @@ -1,8 +1,10 @@ --- -# Test case for TC053 :Openstack Controller Load Balance Service High Availability -# This test case is written by new scenario-based HA testing framework schema: "yardstick:task:0.1" +description: > + Test case for TC053 :Openstack Controller Load Balance Service High Availability; + This test case is written by new scenario-based HA testing framework. + scenarios: - type: "GeneralHA" diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc054.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc054.yaml index 7d94e3de8..93948d3b1 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc054.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc054.yaml @@ -1,8 +1,10 @@ --- -# Test case for TC054 :OpenStack VIP Master Node abnormally shutdown High Availability -# This test case is written by new scenario-based HA testing framework schema: "yardstick:task:0.1" +description: > + Test case for TC054 :OpenStack VIP Master Node abnormally shutdown High Availability; + This test case is written by new scenario-based HA testing framework. + scenarios: - type: "GeneralHA" diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc055.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc055.yaml index 54fc965c6..405247f4e 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc055.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc055.yaml @@ -1,15 +1,16 @@ --- -# Yardstick TC055 config file -# Collect hardware specification from /proc/cpuinfo /proc/meminfo -# compute capacity and scale. - -# the results have -# number of CPUs, number of physical cores in a single CPU -# number of logical cores, total memory size -# cache size per CPU, total cache size -# HT (Hyper-Thread) support status, 1 for open, 0 for close schema: "yardstick:task:0.1" +description: > + Yardstick TC055 config file; + Collect hardware specification from /proc/cpuinfo /proc/meminfo; + compute capacity and scale. + the results have, + number of CPUs, number of physical cores in a single CPU; + number of logical cores, total memory size; + cache size per CPU, total cache size; + HT (Hyper-Thread) support status, 1 for open, 0 for close. + {% set host = host or "node5.yardstick-TC055" %} {% set pod_info = pod_info or "etc/yardstick/nodes/compass_sclab_virtual/pod.yaml" %} scenarios: diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc063.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc063.yaml index 981783765..f1eb3c63e 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc063.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc063.yaml @@ -1,8 +1,10 @@ --- -# Yardstick TC063 config file -# Measure disk size, block size and disk utilization using fdisk and iostat schema: "yardstick:task:0.1" +description: > + Yardstick TC063 config file; + Measure disk size, block size and disk utilization using fdisk and iostat. + {% set host = host or "node5.yardstick-TC063" %} {% set pod_info = pod_info or "etc/yardstick/nodes/compass_sclab_virtual/pod.yaml" %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml index dcc34d80d..a11337d4f 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc069.yaml @@ -1,8 +1,9 @@ --- -# Yardstick TC069 config file -# Measure memory read and write bandwidth using ramspeed schema: "yardstick:task:0.1" +description: > + Yardstick TC069 config file; + Measure memory read and write bandwidth using ramspeed. scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml index 931587b5b..c4ad715ec 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc070.yaml @@ -1,15 +1,15 @@ --- -# Yardstick TC070 config file -# Measure network throughput and packet loss using pktgen. -# Different amounts of flows are tested with, from 2 up to 1001000. -# All tests are run 2 times each. First 2 times with the least -# amount of ports, then 2 times with the next amount of ports, -# and so on until all packet sizes have been run with. -# -# During the measurements memory usage statistics and network latency are -# recorded/measured using free and ping, respectively. schema: "yardstick:task:0.1" +description: > + Yardstick TC070 config file; + Measure network throughput and packet loss using pktgen; + Different amounts of flows are tested with, from 2 up to 1001000; + All tests are run 2 times each. First 2 times with the least + amount of ports, then 2 times with the next amount of ports, + and so on until all packet sizes have been run with; + During the measurements memory usage statistics and network latency are + recorded/measured using free and ping, respectively; scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml index 6f006eeaf..59bfc24bd 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc071.yaml @@ -1,15 +1,15 @@ --- -# Yardstick TC071 config file -# Measure cache hit/miss ratio and usage, network throughput and latency. -# Different amounts of flows are tested with, from 2 up to 1001000. -# All tests are run 2 times each. First 2 times with the least -# amount of ports, then 2 times with the next amount of ports, -# and so on until all packet sizes have been run with. -# -# During the measurements cache hit/miss ration, cache usage statistics and -# network latency are recorded/measured using cachestat and ping, respectively. schema: "yardstick:task:0.1" +description: > + Yardstick TC071 config file; + Measure cache hit/miss ratio and usage, network throughput and latency; + Different amounts of flows are tested with, from 2 up to 1001000; + All tests are run 2 times each. First 2 times with the least + amount of ports, then 2 times with the next amount of ports, + and so on until all packet sizes have been run with; + During the measurements cache hit/miss ration, cache usage statistics and + network latency are recorded/measured using cachestat and ping, respectively; scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml index e1fa33173..10db287cf 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc072.yaml @@ -1,15 +1,15 @@ --- -# Yardstick TC072 config file -# Measure network throughput and packet loss using pktgen. -# Different amounts of flows are tested with, from 2 up to 1001000. -# All tests are run 2 times each. First 2 times with the least -# amount of ports, then 2 times with the next amount of ports, -# and so on until all packet sizes have been run with. -# -# During the measurements network usage statistics and network latency are -# recorded/measured using sar and ping, respectively. schema: "yardstick:task:0.1" +description: > + Yardstick TC072 config file; + Measure network throughput and packet loss using pktgen; + Different amounts of flows are tested with, from 2 up to 1001000; + All tests are run 2 times each. First 2 times with the least + amount of ports, then 2 times with the next amount of ports, + and so on until all packet sizes have been run with; + During the measurements network usage statistics and network latency are + recorded/measured using sar and ping, respectively; scenarios: - diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc073.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc073.yaml index fd95b8c9d..99a0ffe81 100755 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc073.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc073.yaml @@ -1,13 +1,15 @@ --- -# Yardstick TC073 config file -# measure network latency and throughput using netperf -# There are two sample scenarios: bulk test and request/response test -# In bulk test, UDP_STREAM and TCP_STREAM can be used -# send_msg_size and recv_msg_size are options of bulk test -# In req/rsp test, TCP_RR TCP_CRR UDP_RR can be used -# req_rsp_size is option of req/rsp test schema: "yardstick:task:0.1" +description: > + Yardstick TC073 config file; + measure network latency and throughput using netperf; + There are two sample scenarios: bulk test and request/response test; + In bulk test, UDP_STREAM and TCP_STREAM can be used; + send_msg_size and recv_msg_size are options of bulk test; + In req/rsp test, TCP_RR TCP_CRR UDP_RR can be used; + req_rsp_size is option of req/rsp test; + {% set host = host or "node1.LF" %} {% set target = target or "node2.LF" %} {% set pod_info = pod_info or "etc/yardstick/nodes/compass_sclab_physical/pod.yaml" %} diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc074.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc074.yaml index 6dda2d436..3fb3a05be 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc074.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc074.yaml @@ -1,8 +1,10 @@ --- -# Test case for TC074 StorPerf benchmark task config file -# StorPerf is a tool to measure block and object storage performance in an NFVI schema: "yardstick:task:0.1" +description: > + Test case for TC074 StorPerf benchmark task config file; + StorPerf is a tool to measure block and object storage performance in an NFVI. + {% set public_network = public_network or "ext-net" %} {% set StorPerf_ip = StorPerf_ip or "192.168.200.1" %} scenarios: diff --git a/tests/opnfv/test_cases/opnfv_yardstick_tc075.yaml b/tests/opnfv/test_cases/opnfv_yardstick_tc075.yaml index fb5a12e8a..1c1a7e4cd 100644 --- a/tests/opnfv/test_cases/opnfv_yardstick_tc075.yaml +++ b/tests/opnfv/test_cases/opnfv_yardstick_tc075.yaml @@ -1,9 +1,11 @@ --- -# Yardstick TC075 config file -# Measure network capacity and scale. -# Measure number of connections, number of frames received schema: "yardstick:task:0.1" +description: > + Yardstick TC075 config file; + Measure network capacity and scale. + Measure number of connections, number of frames received; + {% set host = host or "node1.LF" %} {% set pod_info = pod_info or "etc/yardstick/nodes/compass_sclab_virtual/pod.yaml" %} 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 aff0cab5c..aff0cab5c 100644 --- a/tests/unit/api/utils/test_influx.py +++ b/tests/unit/apiserver/utils/test_influx.py 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/benchmark/core/test_task.py b/tests/unit/benchmark/core/test_task.py index 5dd32ea17..c56e21047 100644 --- a/tests/unit/benchmark/core/test_task.py +++ b/tests/unit/benchmark/core/test_task.py @@ -24,6 +24,7 @@ except ImportError: from yardstick.benchmark.core import task +from yardstick.common import constants as consts class TaskTestCase(unittest.TestCase): @@ -92,10 +93,10 @@ class TaskTestCase(unittest.TestCase): task_files, task_args, task_args_fnames = t.parse_suite() print("files=%s, args=%s, fnames=%s" % (task_files, task_args, task_args_fnames)) - self.assertEqual(task_files[0], - 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml') - self.assertEqual(task_files[1], - 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml') + self.assertEqual(task_files[0], self.change_to_abspath( + 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml')) + self.assertEqual(task_files[1], self.change_to_abspath( + 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml')) self.assertEqual(task_args[0], None) self.assertEqual(task_args[1], None) self.assertEqual(task_args_fnames[0], None) @@ -109,10 +110,10 @@ class TaskTestCase(unittest.TestCase): task_files, task_args, task_args_fnames = t.parse_suite() print("files=%s, args=%s, fnames=%s" % (task_files, task_args, task_args_fnames)) - self.assertEqual(task_files[0], - 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml') - self.assertEqual(task_files[1], - 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml') + self.assertEqual(task_files[0], self.change_to_abspath( + 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml')) + self.assertEqual(task_files[1], self.change_to_abspath( + 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml')) self.assertEqual(task_args[0], None) self.assertEqual(task_args[1], '{"host": "node1.LF","target": "node2.LF"}') @@ -127,10 +128,10 @@ class TaskTestCase(unittest.TestCase): task_files, task_args, task_args_fnames = t.parse_suite() print("files=%s, args=%s, fnames=%s" % (task_files, task_args, task_args_fnames)) - self.assertEqual(task_files[0], - 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml') - self.assertEqual(task_files[1], - 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml') + self.assertEqual(task_files[0], self.change_to_abspath( + 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml')) + self.assertEqual(task_files[1], self.change_to_abspath( + 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml')) self.assertEqual(task_args[0], None) self.assertEqual(task_args[1], None) self.assertEqual(task_args_fnames[0], None) @@ -144,10 +145,10 @@ class TaskTestCase(unittest.TestCase): task_files, task_args, task_args_fnames = t.parse_suite() print("files=%s, args=%s, fnames=%s" % (task_files, task_args, task_args_fnames)) - self.assertEqual(task_files[0], - 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml') - self.assertEqual(task_files[1], - 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml') + self.assertEqual(task_files[0], self.change_to_abspath( + 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml')) + self.assertEqual(task_files[1], self.change_to_abspath( + 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml')) self.assertEqual(task_args[0], None) self.assertEqual(task_args[1], '{"host": "node1.LF","target": "node2.LF"}') @@ -159,6 +160,9 @@ class TaskTestCase(unittest.TestCase): file_path = os.path.join(curr_path, filename) return file_path + def change_to_abspath(self, filepath): + return os.path.join(consts.YARDSTICK_ROOT_PATH, filepath) + def main(): unittest.main() diff --git a/tests/unit/benchmark/core/test_testcase.py b/tests/unit/benchmark/core/test_testcase.py index c7da2de7c..1f5aad75e 100644 --- a/tests/unit/benchmark/core/test_testcase.py +++ b/tests/unit/benchmark/core/test_testcase.py @@ -28,13 +28,13 @@ class TestcaseUT(unittest.TestCase): def test_list_all(self): t = testcase.Testcase() result = t.list_all("") - self.assertEqual(result, True) + self.assertIsInstance(result, list) def test_show(self): t = testcase.Testcase() casename = Arg() result = t.show(casename) - self.assertEqual(result, True) + self.assertTrue(result) def main(): diff --git a/tests/unit/cmd/commands/test_testcase.py b/tests/unit/cmd/commands/test_testcase.py new file mode 100644 index 000000000..515784352 --- /dev/null +++ b/tests/unit/cmd/commands/test_testcase.py @@ -0,0 +1,21 @@ +import unittest +from mock import patch + +from yardstick.cmd.commands.testcase import TestcaseCommands + + +class TestcaseCommandsUT(unittest.TestCase): + @patch('yardstick.cmd.commands.testcase.TestcaseCommands._format_print') + @patch('yardstick.cmd.commands.client') + def test_do_list(self, mock_client, mock_print): + mock_client.get.return_value = {'result': []} + TestcaseCommands().do_list({}) + self.assertTrue(mock_print.called) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() 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/tests/unit/network_services/test_utils.py b/tests/unit/network_services/test_utils.py new file mode 100644 index 000000000..ecacac7c3 --- /dev/null +++ b/tests/unit/network_services/test_utils.py @@ -0,0 +1,57 @@ +# 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.utils + +from __future__ import absolute_import +import unittest +import mock + +from yardstick.network_services import utils + + +class UtilsTestCase(unittest.TestCase): + """Test all VNF helper methods.""" + + DPDK_PATH = "/opt/nsb_bin/dpdk_nic_bind.py" + + def setUp(self): + super(UtilsTestCase, self).setUp() + + def test_get_nsb_options(self): + result = utils.get_nsb_option("bin_path", None) + self.assertEqual(result, "/opt/nsb_bin") + + def test_get_nsb_optionsi_invalid_key(self): + result = utils.get_nsb_option("bin", None) + self.assertEqual(result, None) + + def test_provision_tool(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(0, self.DPDK_PATH, "")) + ssh.return_value = ssh_mock + tool_path = utils.provision_tool(ssh_mock, self.DPDK_PATH) + self.assertEqual(tool_path, self.DPDK_PATH) + + def test_provision_tool_no_path(self): + with mock.patch("yardstick.ssh.SSH") as ssh: + ssh_mock = mock.Mock(autospec=ssh.SSH) + ssh_mock.execute = \ + mock.Mock(return_value=(1, self.DPDK_PATH, "")) + ssh.return_value = ssh_mock + tool_path = utils.provision_tool(ssh_mock, self.DPDK_PATH) + self.assertEqual(tool_path, self.DPDK_PATH) diff --git a/yardstick/benchmark/contexts/node.py b/yardstick/benchmark/contexts/node.py index e02a71669..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 @@ -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""" 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"] @@ -72,23 +81,28 @@ class NodeContext(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/task.py b/yardstick/benchmark/core/task.py index d05117b47..87d70f42f 100644 --- a/yardstick/benchmark/core/task.py +++ b/yardstick/benchmark/core/task.py @@ -66,8 +66,6 @@ class Task(object): # pragma: no cover if args.parse_only: sys.exit(0) - if os.path.isfile(args.output_file): - os.remove(args.output_file) # parse task_files for i in range(0, len(task_files)): one_task_start_time = time.time() @@ -195,6 +193,8 @@ class TaskParser(object): # pragma: no cover LOG.info("\nStarting scenario:%s", cfg["name"]) test_cases_dir = cfg.get("test_cases_dir", test_cases_dir_default) + test_cases_dir = os.path.join(constants.YARDSTICK_ROOT_PATH, + test_cases_dir) if test_cases_dir[-1] != os.sep: test_cases_dir += os.sep @@ -294,7 +294,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 diff --git a/yardstick/benchmark/core/testcase.py b/yardstick/benchmark/core/testcase.py index 92198bd91..7b23b73aa 100644 --- a/yardstick/benchmark/core/testcase.py +++ b/yardstick/benchmark/core/testcase.py @@ -10,13 +10,15 @@ """ Handler for yardstick command 'testcase' """ from __future__ import absolute_import from __future__ import print_function + import os import yaml -import sys +import logging -from yardstick.benchmark.core import print_hbar from yardstick.common.task_template import TaskTemplate -from yardstick.definitions import YARDSTICK_ROOT_PATH +from yardstick.common import constants as consts + +LOG = logging.getLogger(__name__) class Testcase(object): @@ -25,91 +27,80 @@ class Testcase(object): 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""" - try: - testcase_files = os.listdir(self.test_case_path) - except Exception as e: - print("Failed to list dir:\n%(path)s\n%(err)s\n" - % {"path": self.test_case_path, "err": e}) - raise e - testcase_files.sort() - - for testcase_file in testcase_files: - record = self._get_record(testcase_file) - self.testcase_list.append(record) - - self._format_print(self.testcase_list) - return True + testcase_files = self._get_testcase_file_list() + testcase_list = [self._get_record(f) for f in testcase_files] - def show(self, args): - """Show details of a specific test case""" - testcase_name = args.casename[0] - testcase_path = self.test_case_path + testcase_name + ".yaml" + return testcase_list + + def _get_testcase_file_list(self): try: - with open(testcase_path) as f: - try: - testcase_info = f.read() - print(testcase_info) - - except Exception as e: - print("Failed to load test cases:" - "\n%(testcase_file)s\n%(err)s\n" - % {"testcase_file": testcase_path, "err": e}) - raise e - except IOError as ioerror: - sys.exit(ioerror) - return True + testcase_files = sorted(os.listdir(consts.TESTCASE_DIR)) + except OSError: + LOG.exception('Failed to list dir:\n%s\n', consts.TESTCASE_DIR) + raise + + return testcase_files def _get_record(self, testcase_file): - try: - with open(self.test_case_path + testcase_file) as f: - try: - testcase_info = f.read() - except Exception as e: - print("Failed to load test cases:" - "\n%(testcase_file)s\n%(err)s\n" - % {"testcase_file": testcase_file, "err": e}) - raise e - description, installer, deploy_scenarios = \ - self._parse_testcase(testcase_info) - - record = {'Name': testcase_file.split(".")[0], - 'Description': description, - 'installer': installer, - 'deploy_scenarios': deploy_scenarios} - return record - except IOError as ioerror: - sys.exit(ioerror) + file_path = os.path.join(consts.TESTCASE_DIR, testcase_file) + with open(file_path) as f: + try: + testcase_info = f.read() + except IOError: + LOG.exception('Failed to load test case:\n%s\n', testcase_file) + raise + + description, installer, deploy_scenarios = self._parse_testcase( + testcase_info) + + record = { + 'Name': testcase_file.split(".")[0], + 'Description': description, + 'installer': installer, + 'deploy_scenarios': deploy_scenarios + } + + return record def _parse_testcase(self, testcase_info): - kw = {} - rendered_testcase = TaskTemplate.render(testcase_info, **kw) + rendered_testcase = TaskTemplate.render(testcase_info) testcase_cfg = yaml.load(rendered_testcase) - test_precondition = testcase_cfg.get('precondition', None) - installer_type = 'all' - deploy_scenarios = 'all' - if test_precondition is not None: - installer_type = test_precondition.get('installer_type', 'all') - deploy_scenarios = test_precondition.get('deploy_scenarios', 'all') - - description = testcase_info.split("\n")[2][1:].strip() + + test_precondition = testcase_cfg.get('precondition', {}) + installer_type = test_precondition.get('installer_type', 'all') + deploy_scenarios = test_precondition.get('deploy_scenarios', 'all') + + description = self._get_description(testcase_cfg) + return description, installer_type, deploy_scenarios - def _format_print(self, testcase_list): - """format output""" + def _get_description(self, testcase_cfg): + try: + description_list = testcase_cfg['description'].split(';') + except KeyError: + return '' + else: + try: + return description_list[1].replace(os.linesep, '').strip() + except IndexError: + return description_list[0].replace(os.linesep, '').strip() - print_hbar(88) - print("| %-21s | %-60s" % ("Testcase Name", "Description")) - print_hbar(88) - for testcase_record in testcase_list: - print("| %-16s | %-60s" % (testcase_record['Name'], - testcase_record['Description'])) - print_hbar(88) + def show(self, args): + """Show details of a specific test case""" + testcase_name = args.casename[0] + testcase_path = os.path.join(consts.TESTCASE_DIR, + testcase_name + ".yaml") + with open(testcase_path) as f: + try: + testcase_info = f.read() + except IOError: + LOG.exception('Failed to load test case:\n%s\n', testcase_path) + raise + + print(testcase_info) + return True diff --git a/yardstick/cmd/commands/__init__.py b/yardstick/cmd/commands/__init__.py index 5c5356736..9bc0e9fac 100644 --- a/yardstick/cmd/commands/__init__.py +++ b/yardstick/cmd/commands/__init__.py @@ -1,10 +1,20 @@ from __future__ import absolute_import from yardstick.benchmark.core import Param +from api import client def change_osloobj_to_paras(args): param = Param({}) - for k in param.__dict__: + for k in vars(param): if hasattr(args, k): setattr(param, k, getattr(args, k)) return param + + +class Commands(object): + def __init__(self): + self.client = client + + def _change_to_dict(self, args): + p = Param({}) + return {k: getattr(args, k) for k in vars(p) if hasattr(args, k)} diff --git a/yardstick/cmd/commands/task.py b/yardstick/cmd/commands/task.py index 1c5db1f46..20ab086e5 100644 --- a/yardstick/cmd/commands/task.py +++ b/yardstick/cmd/commands/task.py @@ -1,4 +1,4 @@ -############################################################################## +############################################################################# # Copyright (c) 2015 Ericsson AB and others. # # All rights reserved. This program and the accompanying materials @@ -9,10 +9,12 @@ """ Handler for yardstick command 'task' """ from __future__ import print_function - from __future__ import absolute_import + from yardstick.benchmark.core.task import Task from yardstick.common.utils import cliargs +from yardstick.common.utils import write_json_to_file +from yardstick.common import constants as consts from yardstick.cmd.commands import change_osloobj_to_paras output_file_default = "/tmp/yardstick.out" @@ -42,4 +44,18 @@ class TaskCommands(object): action="store_true") def do_start(self, args, **kwargs): param = change_osloobj_to_paras(args) - Task().start(param) + + self._init_result_file() + + try: + Task().start(param) + except Exception as e: + self._write_error_data(e) + + def _init_result_file(self): + data = {'status': 0, 'result': []} + write_json_to_file(consts.DEFAULT_OUTPUT_FILE, data) + + def _write_error_data(self, error): + data = {'status': 2, 'result': str(error)} + write_json_to_file(consts.DEFAULT_OUTPUT_FILE, data) diff --git a/yardstick/cmd/commands/testcase.py b/yardstick/cmd/commands/testcase.py index bd17b1aa5..a151871b3 100644 --- a/yardstick/cmd/commands/testcase.py +++ b/yardstick/cmd/commands/testcase.py @@ -9,14 +9,16 @@ """ Handler for yardstick command 'testcase' """ from __future__ import print_function - from __future__ import absolute_import + from yardstick.benchmark.core.testcase import Testcase +from yardstick.benchmark.core import print_hbar from yardstick.common.utils import cliargs from yardstick.cmd.commands import change_osloobj_to_paras +from yardstick.cmd.commands import Commands -class TestcaseCommands(object): +class TestcaseCommands(Commands): """Testcase commands. Set of commands to discover and display test cases. @@ -24,11 +26,22 @@ class TestcaseCommands(object): def do_list(self, args): """List existing test cases""" - param = change_osloobj_to_paras(args) - Testcase().list_all(param) + testcase_list = self.client.get('/yardstick/testcases')['result'] + self._format_print(testcase_list) @cliargs("casename", type=str, help="test case name", nargs=1) def do_show(self, args): """Show details of a specific test case""" param = change_osloobj_to_paras(args) Testcase().show(param) + + def _format_print(self, testcase_list): + """format output""" + + print_hbar(88) + print("| %-21s | %-60s" % ("Testcase Name", "Description")) + print_hbar(88) + for testcase_record in testcase_list: + print("| %-16s | %-60s" % (testcase_record['Name'], + testcase_record['Description'])) + print_hbar(88) diff --git a/yardstick/common/constants.py b/yardstick/common/constants.py index d99e216f4..e6faf6828 100644 --- a/yardstick/common/constants.py +++ b/yardstick/common/constants.py @@ -31,6 +31,8 @@ INSTALLERS = ['apex', 'compass', 'fuel', 'joid'] YARDSTICK_ROOT_PATH = dirname(dirname(dirname(abspath(__file__)))) + sep +TESTCASE_DIR = join(YARDSTICK_ROOT_PATH, 'tests/opnfv/test_cases/') + YARDSTICK_REPOS_DIR = '/home/opnfv/repos/yardstick' YARDSTICK_CONFIG_DIR = '/etc/yardstick/' @@ -55,3 +57,7 @@ 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' + +DEFAULT_OUTPUT_FILE = '/tmp/yardstick.out' diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py index 57ace14e6..473bbf540 100644 --- a/yardstick/common/utils.py +++ b/yardstick/common/utils.py @@ -30,6 +30,7 @@ from keystoneauth1 import identity from keystoneauth1 import session from neutronclient.v2_0 import client from oslo_utils import importutils +from oslo_serialization import jsonutils import yardstick @@ -145,3 +146,12 @@ def get_neutron_client(): sess = get_openstack_session() neutron_client = client.Client(session=sess) return neutron_client + + +def write_json_to_file(path, data, mode='w'): + write_file(path, jsonutils.dump_as_bytes(data), mode) + + +def write_file(path, data, mode='w'): + with open(path, mode) as f: + f.write(data) diff --git a/yardstick/dispatcher/file.py b/yardstick/dispatcher/file.py index 9c728e983..8d3c3693d 100644 --- a/yardstick/dispatcher/file.py +++ b/yardstick/dispatcher/file.py @@ -18,28 +18,9 @@ from __future__ import absolute_import -import logging -import logging.handlers - -from oslo_serialization import jsonutils -from oslo_config import cfg - from yardstick.dispatcher.base import Base as DispatchBase - -CONF = cfg.CONF -OPTS = [ - cfg.StrOpt('file_path', - default='/tmp/yardstick.out', - help='Name and the location of the file to record ' - 'data.'), - cfg.IntOpt('max_bytes', - default=0, - help='The max size of the file.'), - cfg.IntOpt('backup_count', - default=0, - help='The max number of the files to keep.'), -] -CONF.register_opts(OPTS, group="dispatcher_file") +from yardstick.common import constants as consts +from yardstick.common import utils class FileDispatcher(DispatchBase): @@ -50,29 +31,13 @@ class FileDispatcher(DispatchBase): def __init__(self, conf): super(FileDispatcher, self).__init__(conf) - self.log = None - - # if the directory and path are configured, then log to the file - if CONF.dispatcher_file.file_path: - dispatcher_logger = logging.Logger('dispatcher.file') - dispatcher_logger.setLevel(logging.INFO) - # create rotating file handler which logs result - rfh = logging.handlers.RotatingFileHandler( - self.conf.get('file_path', CONF.dispatcher_file.file_path), - maxBytes=CONF.dispatcher_file.max_bytes, - backupCount=CONF.dispatcher_file.backup_count, - encoding='utf8') - - rfh.setLevel(logging.INFO) - # Only wanted the data to be saved in the file, not the - # project root logger. - dispatcher_logger.propagate = False - dispatcher_logger.addHandler(rfh) - self.log = dispatcher_logger + self.result = [] def record_result_data(self, data): - if self.log: - self.log.info(jsonutils.dump_as_bytes(data)) + self.result.append(data) def flush_result_data(self): - pass + file_path = self.conf.get('file_path', consts.DEFAULT_OUTPUT_FILE) + + data = {'status': 1, 'result': self.result} + utils.write_json_to_file(file_path, data) 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/network_services/utils.py b/yardstick/network_services/utils.py new file mode 100644 index 000000000..80e0a631c --- /dev/null +++ b/yardstick/network_services/utils.py @@ -0,0 +1,62 @@ +# 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. +""" Helper function to get Network Service testing configuration """ + +from __future__ import absolute_import +import logging + +from oslo_config import cfg +from oslo_config.cfg import NoSuchOptError +from oslo_utils import encodeutils + +CONF = cfg.CONF +OPTS = [ + cfg.StrOpt('bin_path', + default='/opt/nsb_bin', + help='bin_path for VNFs location.'), + cfg.StrOpt('trex_path', + default='/opt/nsb_bin/trex/scripts', + help='trex automation lib pathh.'), +] +CONF.register_opts(OPTS, group="nsb") + + +def get_nsb_option(option, default=None): + """return requested option for yardstick.conf""" + + try: + return CONF.nsb.__getitem__(option) + except NoSuchOptError: + logging.debug("Invalid key %s", option) + else: + return default + + +def provision_tool(connection, tool_path): + """ + verify if the tool path exits on the node, + if not push the local binary to remote node + + :return - Tool path + """ + bin_path = get_nsb_option("bin_path") + exit_status, stdout = connection.execute("which %s" % tool_path)[:2] + if exit_status == 0: + return encodeutils.safe_encode(stdout, incoming='utf-8').rstrip() + + logging.warning("%s not found on %s, will try to copy from localhost", + tool_path, connection.host) + connection.execute('mkdir -p "%s"' % bin_path) + connection.put(tool_path, tool_path) + return tool_path 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: |