summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/resources/v1/env.py4
-rw-r--r--api/resources/v2/pods.py3
-rw-r--r--gui/app/scripts/controllers/container.controller.js2
-rw-r--r--gui/app/scripts/controllers/content.controller.js30
-rw-r--r--gui/app/scripts/controllers/detail.controller.js5
-rw-r--r--gui/app/scripts/controllers/image.controller.js2
-rw-r--r--gui/app/scripts/controllers/main.js8
-rw-r--r--gui/app/scripts/controllers/pod.controller.js2
-rw-r--r--gui/app/scripts/controllers/project.controller.js2
-rw-r--r--gui/app/scripts/controllers/projectDetail.controller.js6
-rw-r--r--gui/app/scripts/controllers/testcase.controller.js4
-rw-r--r--gui/app/scripts/controllers/testsuit.controller.js6
-rw-r--r--gui/app/scripts/router.config.js32
-rw-r--r--gui/app/styles/main.css6
-rw-r--r--gui/app/views/layout/sideNav.html17
-rw-r--r--gui/app/views/layout/sideNav2.html108
-rw-r--r--gui/app/views/main2.html174
-rwxr-xr-xnsb_setup.sh8
-rw-r--r--samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_1b_Requests-65000_Concurrency.yaml2
-rw-r--r--samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_ixia.yaml2
-rw-r--r--samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml5
-rwxr-xr-xtests/ci/apexlake-verify29
-rw-r--r--tests/unit/benchmark/contexts/standalone/__init__.py0
-rw-r--r--tests/unit/benchmark/contexts/standalone/ovs_sample_password.yaml (renamed from tests/unit/benchmark/contexts/ovs_sample_password.yaml)0
-rw-r--r--tests/unit/benchmark/contexts/standalone/ovs_sample_ssh_key.yaml (renamed from tests/unit/benchmark/contexts/ovs_sample_ssh_key.yaml)0
-rw-r--r--tests/unit/benchmark/contexts/standalone/ovs_sample_write_to_file.txt (renamed from tests/unit/benchmark/contexts/ovs_sample_write_to_file.txt)0
-rw-r--r--tests/unit/benchmark/contexts/standalone/sriov_sample_password.yaml (renamed from tests/unit/benchmark/contexts/sriov_sample_password.yaml)0
-rw-r--r--tests/unit/benchmark/contexts/standalone/sriov_sample_ssh_key.yaml (renamed from tests/unit/benchmark/contexts/sriov_sample_ssh_key.yaml)0
-rw-r--r--tests/unit/benchmark/contexts/standalone/sriov_sample_write_to_file.txt (renamed from tests/unit/benchmark/contexts/sriov_sample_write_to_file.txt)0
-rw-r--r--tests/unit/benchmark/contexts/standalone/test_ovsdpdk.py (renamed from tests/unit/benchmark/contexts/test_ovsdpdk.py)10
-rw-r--r--tests/unit/benchmark/contexts/standalone/test_sriov.py (renamed from tests/unit/benchmark/contexts/test_sriov.py)14
-rw-r--r--tests/unit/benchmark/contexts/test_standalone.py17
-rw-r--r--tests/unit/benchmark/core/test_task.py3
-rw-r--r--tests/unit/benchmark/scenarios/lib/test_attach_volume.py33
-rw-r--r--tests/unit/benchmark/scenarios/lib/test_create_floating_ip.py34
-rw-r--r--tests/unit/benchmark/scenarios/lib/test_create_keypair.py35
-rw-r--r--tests/unit/benchmark/scenarios/lib/test_get_numa_info.py6
-rw-r--r--tests/unit/benchmark/scenarios/networking/test_vnf_generic.py8
-rw-r--r--tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py2
-rw-r--r--tests/unit/common/test_utils.py35
-rw-r--r--tests/unit/common/test_yaml_loader.py32
-rw-r--r--tests/unit/network_services/libs/ixia_libs/test_IxNet.py15
-rw-r--r--tests/unit/network_services/nfvi/test_resource.py4
-rw-r--r--tests/unit/network_services/test_yang_model.py2
-rw-r--r--tests/unit/network_services/traffic_profile/test_http_ixload.py24
-rw-r--r--tests/unit/network_services/vnf_generic/test_vnfdgen.py65
-rw-r--r--tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py2
-rw-r--r--yardstick/benchmark/contexts/node.py4
-rw-r--r--yardstick/benchmark/contexts/standalone/__init__.py (renamed from yardstick/benchmark/contexts/standalone.py)4
-rw-r--r--yardstick/benchmark/contexts/standalone/ovsdpdk.py (renamed from yardstick/benchmark/contexts/ovsdpdk.py)0
-rw-r--r--yardstick/benchmark/contexts/standalone/sriov.py (renamed from yardstick/benchmark/contexts/sriov.py)0
-rw-r--r--yardstick/benchmark/core/plugin.py4
-rw-r--r--yardstick/benchmark/core/task.py8
-rw-r--r--yardstick/benchmark/core/testcase.py4
-rw-r--r--yardstick/benchmark/scenarios/availability/attacker/baseattacker.py4
-rw-r--r--yardstick/benchmark/scenarios/availability/monitor/basemonitor.py5
-rw-r--r--yardstick/benchmark/scenarios/availability/operation/baseoperation.py4
-rw-r--r--yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py4
-rw-r--r--yardstick/benchmark/scenarios/lib/attach_volume.py53
-rw-r--r--yardstick/benchmark/scenarios/lib/create_floating_ip.py60
-rw-r--r--yardstick/benchmark/scenarios/lib/create_keypair.py69
-rw-r--r--yardstick/benchmark/scenarios/lib/get_numa_info.py4
-rw-r--r--yardstick/benchmark/scenarios/networking/vnf_generic.py81
-rw-r--r--yardstick/common/html_template.py4
-rw-r--r--yardstick/common/openstack_utils.py32
-rwxr-xr-xyardstick/common/task_template.py18
-rw-r--r--yardstick/common/template_format.py8
-rw-r--r--yardstick/common/utils.py30
-rw-r--r--yardstick/common/yaml_loader.py33
-rw-r--r--yardstick/network_services/helpers/samplevnf_helper.py7
-rw-r--r--yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py17
-rw-r--r--yardstick/network_services/nfvi/resource.py32
-rw-r--r--yardstick/network_services/traffic_profile/http_ixload.py34
-rw-r--r--yardstick/network_services/vnf_generic/vnf/sample_vnf.py35
-rw-r--r--yardstick/network_services/vnf_generic/vnf/tg_ixload.py11
-rw-r--r--yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py24
-rw-r--r--yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py7
-rw-r--r--yardstick/network_services/vnf_generic/vnfdgen.py22
-rw-r--r--yardstick/network_services/yang_model.py215
79 files changed, 945 insertions, 690 deletions
diff --git a/api/resources/v1/env.py b/api/resources/v1/env.py
index 8367fa9eb..98b8ec7e4 100644
--- a/api/resources/v1/env.py
+++ b/api/resources/v1/env.py
@@ -31,7 +31,7 @@ from yardstick.common import utils
from yardstick.common.utils import result_handler
from yardstick.common import openstack_utils
from yardstick.common.httpClient import HttpClient
-
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
LOG.setLevel(logging.DEBUG)
@@ -393,7 +393,7 @@ class V1Env(ApiResource):
return result_handler(consts.API_ERROR, 'file must be provided')
LOG.info('Checking file')
- data = yaml.safe_load(pod_file.read())
+ data = yaml_load(pod_file.read())
if not isinstance(data, collections.Mapping):
return result_handler(consts.API_ERROR, 'invalid yaml file')
diff --git a/api/resources/v2/pods.py b/api/resources/v2/pods.py
index f2316d353..d98238ca1 100644
--- a/api/resources/v2/pods.py
+++ b/api/resources/v2/pods.py
@@ -18,6 +18,7 @@ from api.database.v2.handlers import V2EnvironmentHandler
from yardstick.common import constants as consts
from yardstick.common.utils import result_handler
from yardstick.common.task_template import TaskTemplate
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
LOG.setLevel(logging.DEBUG)
@@ -48,7 +49,7 @@ class V2Pods(ApiResource):
upload_file.save(consts.POD_FILE)
with open(consts.POD_FILE) as f:
- data = yaml.safe_load(TaskTemplate.render(f.read()))
+ data = yaml_load(TaskTemplate.render(f.read()))
LOG.debug('pod content is: %s', data)
LOG.info('create pod in database')
diff --git a/gui/app/scripts/controllers/container.controller.js b/gui/app/scripts/controllers/container.controller.js
index 6c2ccd8ff..3ad200a91 100644
--- a/gui/app/scripts/controllers/container.controller.js
+++ b/gui/app/scripts/controllers/container.controller.js
@@ -128,7 +128,7 @@ angular.module('yardStickGui2App')
$scope.selectContainer = name;
}
$scope.goBack = function goBack() {
- $state.go('app2.projectList');
+ $state.go('app.projectList');
}
$scope.openDeleteEnv = function openDeleteEnv(id, name) {
diff --git a/gui/app/scripts/controllers/content.controller.js b/gui/app/scripts/controllers/content.controller.js
index d2bc19eea..0288fa540 100644
--- a/gui/app/scripts/controllers/content.controller.js
+++ b/gui/app/scripts/controllers/content.controller.js
@@ -2,7 +2,7 @@
angular.module('yardStickGui2App')
.controller('ContentController', ['$scope', '$state', '$stateParams', 'mainFactory', 'Upload', 'toaster', '$location', '$localStorage',
- function($scope, $state, $stateParams, mainFactory, Upload, toaster, $location, $localStorage) {
+ function ($scope, $state, $stateParams, mainFactory, Upload, toaster, $location, $localStorage) {
@@ -11,10 +11,11 @@ angular.module('yardStickGui2App')
$scope.showEnvironment = false;
$scope.counldGoDetail = false;
$scope.activeStatus = 0;
+ $scope.ifshowEnvChild = false;
- $scope.$watch(function() {
+ $scope.$watch(function () {
return location.hash
- }, function(newvalue, oldvalue) {
+ }, function (newvalue, oldvalue) {
if (location.hash.indexOf('project') > -1) {
$scope.projectShow = true;
$scope.taskShow = false;
@@ -26,6 +27,13 @@ angular.module('yardStickGui2App')
$scope.reportShow = true;
$scope.taskShow = true;
$scope.projectShow = true;
+ } else if (location.hash.indexOf('envDetail') > -1 || location.hash.indexOf('envimageDetail') > -1 ||
+ location.hash.indexOf('envpodupload') > -1 || location.hash.indexOf('envcontainer') > -1) {
+ $scope.ifshowEnvChild = true;
+ $scope.activeStatus=0;
+ }else{
+ $scope.ifshowEnvChild=false;
+ $scope.activeStatus=-1;
}
})
@@ -88,30 +96,30 @@ angular.module('yardStickGui2App')
}
function gotoTestcase() {
- $state.go('app2.testcase');
+ $state.go('app.testcase');
}
function gotoEnviron() {
if ($location.path().indexOf('env') > -1 || $location.path().indexOf('environment') > -1) {
$scope.counldGoDetail = true;
}
- $state.go('app2.environment');
+ $state.go('app.environment');
}
function gotoSuite() {
- $state.go('app2.testsuite');
+ $state.go('app.testsuite');
}
function gotoProject() {
- $state.go('app2.projectList');
+ $state.go('app.projectList');
}
function gotoTask() {
- $state.go('app2.tasklist');
+ $state.go('app.tasklist');
}
function gotoReport() {
- $state.go('app2.report');
+ $state.go('app.report');
}
function goBack() {
@@ -119,7 +127,7 @@ angular.module('yardStickGui2App')
return;
} else if ($location.path().indexOf('main/envDetail/') || $location.path().indexOf('main/imageDetail/') ||
$location.path().indexOf('main/podupload/') || $location.path().indexOf('main/container/')) {
- $state.go('app2.environment');
+ $state.go('app.environment');
return;
} else {
window.history.back();
@@ -133,4 +141,4 @@ angular.module('yardStickGui2App')
}
- ]); \ No newline at end of file
+ ]);
diff --git a/gui/app/scripts/controllers/detail.controller.js b/gui/app/scripts/controllers/detail.controller.js
index 3e2eaa100..bfdb525f7 100644
--- a/gui/app/scripts/controllers/detail.controller.js
+++ b/gui/app/scripts/controllers/detail.controller.js
@@ -108,6 +108,7 @@ angular.module('yardStickGui2App')
//buildtoEnvInfo
function buildToEnvInfo(object) {
+ $scope.envInfo=[];
var tempKeyArray = Object.keys(object);
for (var i = 0; i < tempKeyArray.length; i++) {
@@ -118,7 +119,11 @@ angular.module('yardStickGui2App')
value: tempValue
};
$scope.envInfo.push(temp);
+
}
+
+ console.log($scope.envInfo);
+ console.log($scope.openrcInfo);
}
function uploadFiles($file, $invalidFiles) {
diff --git a/gui/app/scripts/controllers/image.controller.js b/gui/app/scripts/controllers/image.controller.js
index 53acff405..f6c91592f 100644
--- a/gui/app/scripts/controllers/image.controller.js
+++ b/gui/app/scripts/controllers/image.controller.js
@@ -149,7 +149,7 @@ angular.module('yardStickGui2App')
}
$scope.goBack = function goBack() {
- $state.go('app2.projectList');
+ $state.go('app.projectList');
}
$scope.goNext = function goNext() {
diff --git a/gui/app/scripts/controllers/main.js b/gui/app/scripts/controllers/main.js
index e3e880e62..ab76bf0f2 100644
--- a/gui/app/scripts/controllers/main.js
+++ b/gui/app/scripts/controllers/main.js
@@ -18,11 +18,7 @@ angular.module('yardStickGui2App')
$scope.showNextPod = null;
$scope.displayContainerInfo = [];
$scope.containerList = [{ value: 'create_influxdb', name: "InfluxDB" }, { value: 'create_grafana', name: "Grafana" }]
- $scope.items = [
- 'The first choice!',
- 'And another choice for you.',
- 'but wait! A third!'
- ];
+
$scope.$on('$destroy', function() {
$interval.cancel($scope.intervalImgae)
});
@@ -381,7 +377,7 @@ angular.module('yardStickGui2App')
$scope.goBack = function goBack() {
- $state.go('app2.projectList');
+ $state.go('app.projectList');
}
$scope.displayContainerInfo = [];
diff --git a/gui/app/scripts/controllers/pod.controller.js b/gui/app/scripts/controllers/pod.controller.js
index 3ef236854..56dfee148 100644
--- a/gui/app/scripts/controllers/pod.controller.js
+++ b/gui/app/scripts/controllers/pod.controller.js
@@ -113,7 +113,7 @@ angular.module('yardStickGui2App')
}
$scope.goBack = function goBack() {
- $state.go('app2.projectList');
+ $state.go('app.projectList');
}
diff --git a/gui/app/scripts/controllers/project.controller.js b/gui/app/scripts/controllers/project.controller.js
index 0a7b8b932..197474567 100644
--- a/gui/app/scripts/controllers/project.controller.js
+++ b/gui/app/scripts/controllers/project.controller.js
@@ -91,7 +91,7 @@ angular.module('yardStickGui2App')
}
function gotoDetail(id) {
- $state.go('app2.projectdetail', { projectId: id })
+ $state.go('app.projectdetail', { projectId: id })
}
diff --git a/gui/app/scripts/controllers/projectDetail.controller.js b/gui/app/scripts/controllers/projectDetail.controller.js
index a616f3ee7..843f66c57 100644
--- a/gui/app/scripts/controllers/projectDetail.controller.js
+++ b/gui/app/scripts/controllers/projectDetail.controller.js
@@ -606,16 +606,16 @@ angular.module('yardStickGui2App')
function gotoDetail(id) {
- $state.go('app2.tasklist', { taskId: id });
+ $state.go('app.tasklist', { taskId: id });
}
function gotoReport(id) {
- $state.go('app2.report', { taskId: id });
+ $state.go('app.report', { taskId: id });
}
function gotoModify(id) {
- $state.go('app2.taskModify', { taskId: id });
+ $state.go('app.taskModify', { taskId: id });
}
function goBack() {
diff --git a/gui/app/scripts/controllers/testcase.controller.js b/gui/app/scripts/controllers/testcase.controller.js
index 616ceb4a8..c93fd8cb0 100644
--- a/gui/app/scripts/controllers/testcase.controller.js
+++ b/gui/app/scripts/controllers/testcase.controller.js
@@ -41,7 +41,7 @@ angular.module('yardStickGui2App')
}
function gotoDetail(name) {
- $state.go('app2.testcasedetail', { name: name });
+ $state.go('app.testcasedetail', { name: name });
}
@@ -93,7 +93,7 @@ angular.module('yardStickGui2App')
}
$scope.goBack = function goBack() {
- $state.go('app2.projectList');
+ $state.go('app.projectList');
}
$scope.openDeleteEnv = function openDeleteEnv(id, name) {
diff --git a/gui/app/scripts/controllers/testsuit.controller.js b/gui/app/scripts/controllers/testsuit.controller.js
index abc9095c7..a15daa776 100644
--- a/gui/app/scripts/controllers/testsuit.controller.js
+++ b/gui/app/scripts/controllers/testsuit.controller.js
@@ -41,16 +41,16 @@ angular.module('yardStickGui2App')
function gotoDetail(name) {
var temp = name.split('.')[0];
- $state.go('app2.suitedetail', { name: temp })
+ $state.go('app.suitedetail', { name: temp })
}
function gotoCreateSuite() {
- $state.go('app2.suitcreate');
+ $state.go('app.suitcreate');
}
$scope.goBack = function goBack() {
- $state.go('app2.projectList');
+ $state.go('app.projectList');
}
diff --git a/gui/app/scripts/router.config.js b/gui/app/scripts/router.config.js
index 9d3c045bd..da2eb086b 100644
--- a/gui/app/scripts/router.config.js
+++ b/gui/app/scripts/router.config.js
@@ -20,14 +20,6 @@ angular.module('yardStickGui2App')
$stateProvider
- .state('app2', {
- url: "/main",
- controller: 'ContentController',
- templateUrl: "views/main2.html",
- ncyBreadcrumb: {
- label: 'Main'
- }
- })
.state('app', {
url: "/main",
controller: 'ContentController',
@@ -37,7 +29,7 @@ angular.module('yardStickGui2App')
}
})
- .state('app2.environment', {
+ .state('app.environment', {
url: '/environment',
templateUrl: 'views/environmentList.html',
controller: 'MainCtrl',
@@ -45,7 +37,7 @@ angular.module('yardStickGui2App')
label: 'Environment'
}
})
- .state('app2.testcase', {
+ .state('app.testcase', {
url: '/testcase',
templateUrl: 'views/testcaselist.html',
controller: 'TestcaseController',
@@ -53,7 +45,7 @@ angular.module('yardStickGui2App')
label: 'Test Case'
}
})
- .state('app2.testsuite', {
+ .state('app.testsuite', {
url: '/suite',
templateUrl: 'views/suite.html',
controller: 'SuiteListController',
@@ -61,7 +53,7 @@ angular.module('yardStickGui2App')
label: 'Test Suite'
}
})
- .state('app2.suitcreate', {
+ .state('app.suitcreate', {
url: '/suitcreate',
templateUrl: 'views/testcasechoose.html',
controller: 'suitcreateController',
@@ -69,7 +61,7 @@ angular.module('yardStickGui2App')
label: 'Suite Create'
}
})
- .state('app2.testcasedetail', {
+ .state('app.testcasedetail', {
url: '/testdetail/:name',
templateUrl: 'views/testcasedetail.html',
controller: 'testcaseDetailController',
@@ -78,7 +70,7 @@ angular.module('yardStickGui2App')
},
params: { name: null }
})
- .state('app2.suitedetail', {
+ .state('app.suitedetail', {
url: '/suitedetail/:name',
templateUrl: 'views/suitedetail.html',
controller: 'suiteDetailController',
@@ -124,7 +116,7 @@ angular.module('yardStickGui2App')
label: 'Container Manage'
}
})
- .state('app2.projectList', {
+ .state('app.projectList', {
url: '/project',
templateUrl: 'views/projectList.html',
controller: 'ProjectController',
@@ -133,7 +125,7 @@ angular.module('yardStickGui2App')
}
})
- .state('app2.tasklist', {
+ .state('app.tasklist', {
url: '/task/:taskId',
templateUrl: 'views/taskList.html',
controller: 'TaskController',
@@ -143,7 +135,7 @@ angular.module('yardStickGui2App')
}
})
- .state('app2.taskLog', {
+ .state('app.taskLog', {
url: '/task/:taskId/log',
templateUrl: 'views/taskLog.html',
controller: 'TaskLogController',
@@ -153,7 +145,7 @@ angular.module('yardStickGui2App')
}
})
- .state('app2.report', {
+ .state('app.report', {
url: '/report/:taskId',
templateUrl: 'views/report.html',
controller: 'ReportController',
@@ -163,7 +155,7 @@ angular.module('yardStickGui2App')
}
})
- .state('app2.projectdetail', {
+ .state('app.projectdetail', {
url: '/projectdetail/:projectId',
templateUrl: 'views/projectdetail.html',
controller: 'ProjectDetailController',
@@ -173,7 +165,7 @@ angular.module('yardStickGui2App')
}
})
- .state('app2.taskModify', {
+ .state('app.taskModify', {
url: '/taskModify/:taskId',
templateUrl: 'views/taskmodify.html',
controller: 'TaskModifyController',
diff --git a/gui/app/styles/main.css b/gui/app/styles/main.css
index e13a66bce..d2ea8ba42 100644
--- a/gui/app/styles/main.css
+++ b/gui/app/styles/main.css
@@ -20,6 +20,8 @@ body {
}
+
+
/* Custom page header */
.header {
@@ -206,3 +208,7 @@ input:focus{outline: 0}
overflow: hidden;
}
+.bs-sidenav{
+ margin-top:21px !important;
+}
+
diff --git a/gui/app/views/layout/sideNav.html b/gui/app/views/layout/sideNav.html
index 4fc99cd4f..6c4426307 100644
--- a/gui/app/views/layout/sideNav.html
+++ b/gui/app/views/layout/sideNav.html
@@ -18,7 +18,7 @@
</div>
</div>
- <div class="panel-group" role="tablist" aria-multiselectable="true" bs-collapse style="margin-bottom:0px;" ng-model="activeStatus">
+ <div class="panel-group" role="tablist" aria-multiselectable="true" bs-collapse style="margin-bottom:0px;" ng-model="activeStatus" ng-if="ifshowEnvChild">
<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
@@ -48,6 +48,19 @@
</div>
</div>
</div>
+ <div class="panel-group" role="tablist" aria-multiselectable="false" bs-collapse style="margin-bottom:0px;" ng-if="!ifshowEnvChild">
+ <div class="panel panel-default">
+ <div class="panel-heading" role="tab">
+ <h4 class="panel-title">
+ <a bs-collapse-toggle style=" text-decoration: none;">
+ <div style="display:inline;" ng-click="gotoEnviron()">Environment </div>
+ <!--<i class="fa fa-sort-asc" aria-hidden="true" style="margin-left: 71px;display:inline"></i>-->
+ </a>
+ </h4>
+ </div>
+
+ </div>
+ </div>
<div class="panel-group " role="tablist " aria-multiselectable="true " bs-collapse style="margin-bottom:0px; ">
<div class="panel panel-default ">
@@ -138,4 +151,4 @@
.active.panel-body {
background-color: #dfe3e4;
}
-</style>
+</style> \ No newline at end of file
diff --git a/gui/app/views/layout/sideNav2.html b/gui/app/views/layout/sideNav2.html
deleted file mode 100644
index 93e0de4be..000000000
--- a/gui/app/views/layout/sideNav2.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<div class="naviSide">
-
-
- <ul class="nav bs-sidenav">
-
- <div class="panel-group " role="tablist " aria-multiselectable="true " bs-collapse style="margin-bottom:0px; ">
- <div class="panel panel-default ">
- <div class="panel-heading " role="tab ">
- <h4 class="panel-title ">
- <a bs-collapse-toggle style=" text-decoration: none;" ng-click="gotoProject();">
- Project
- </a>
- </h4>
-
- </div>
-
- </div>
- </div>
- <div class="panel-group" role="tablist" aria-multiselectable="false" bs-collapse style="margin-bottom:0px;">
- <div class="panel panel-default">
- <div class="panel-heading" role="tab">
- <h4 class="panel-title">
- <a bs-collapse-toggle style=" text-decoration: none;">
- <div style="display:inline;" ng-click="gotoEnviron()">Environment </div>
- <!--<i class="fa fa-sort-asc" aria-hidden="true" style="margin-left: 71px;display:inline"></i>-->
- </a>
- </h4>
- </div>
-
- </div>
- </div>
-
- <div class="panel-group " role="tablist " aria-multiselectable="true " bs-collapse style="margin-bottom:0px; ">
- <div class="panel panel-default ">
- <div class="panel-heading " role="tab ">
- <h4 class="panel-title ">
- <a bs-collapse-toggle style=" text-decoration: none;" ng-click="gotoTestcase()">
- Test Case
- </a>
- </h4>
-
- </div>
-
- </div>
- </div>
-
- <div class="panel-group " role="tablist " aria-multiselectable="true " bs-collapse style="margin-bottom:0px; ">
- <div class="panel panel-default ">
- <div class="panel-heading " role="tab ">
- <h4 class="panel-title ">
- <a bs-collapse-toggle style=" text-decoration: none;" ng-click="gotoSuite()">
- Test Suite
- </a>
- </h4>
-
- </div>
-
- </div>
- </div>
-
-
-
- </ul>
-
-</div>
-
-<style>
- .bs-sidenav {
- margin-top: 21px;
- margin-bottom: 20px;
- width: 124px;
- }
-
- .nav {
- margin-bottom: 0;
- padding-left: 0;
- list-style: none;
- }
-
- .nav>li {
- position: relative;
- display: block;
- }
-
- li {
- display: list-item;
- text-align: -webkit-match-parent;
- }
-
- a {
- cursor: pointer;
- }
-
- a.active {
- background-color: #EEEEEE;
- border-radius: 5px;
- width: 165px;
- }
- /*a:hover {
- width: 165px;
- }*/
-
- .nav>li>a:hover,
- .nav>li>a:focus {
- text-decoration: underline;
- background-color: transparent;
- }
-</style>
diff --git a/gui/app/views/main2.html b/gui/app/views/main2.html
deleted file mode 100644
index 3f49e82e0..000000000
--- a/gui/app/views/main2.html
+++ /dev/null
@@ -1,174 +0,0 @@
-<div>
- <div ng-include="'views/layout/header.html'"></div>
-</div>
-<div ng-include="'views/layout/sideNav2.html'"></div>
-
-
-<div style="margin-top:80px;margin-left:220px;">
- <!--<div ncy-breadcrumb></div>-->
- <div>
- <ol class="progressDefine">
- <li data-step="1" ng-click="gotoProject();" style="cursor:pointer" ng-class="{'is-complete':projectShow}">
- Project
- </li>
- <li data-step="2" ng-class="{'is-complete':taskShow}">
- Task
- </li>
-
- <li data-step="3" ng-class="{'is-complete':reportShow}">
- Reporting
- </li>
-
- </ol>
- </div>
-
-
-</div>
-
-
-
-
-
-
-
-
-
-<div ui-view></div>
-
-
-
-<style>
- .stepsContent {
- display: flex;
- flex-direction: row;
- justify-content: space-around;
- margin-left: 120px;
- margin-top: 100px;
- }
-
- .stepItem {
- display: flex;
- flex-direction: column;
- }
-
- .nextButton {
- margin-left: 500px;
- }
-
- .progressDefine {
- list-style: none;
- margin: 0;
- padding: 0;
- display: table;
- table-layout: fixed;
- width: 100%;
- color: #849397;
- }
-
- .progressDefine>li {
- position: relative;
- display: table-cell;
- text-align: center;
- font-size: 0.8em;
- }
-
- .progressDefine>li:before {
- content: attr(data-step);
- display: block;
- margin: 0 auto;
- background: #DFE3E4;
- width: 3em;
- height: 3em;
- text-align: center;
- margin-bottom: 0.25em;
- line-height: 3em;
- border-radius: 100%;
- position: relative;
- z-index: 5;
- }
-
- .progressDefine>li:after {
- content: '';
- position: absolute;
- display: block;
- background: #DFE3E4;
- width: 100%;
- height: 0.5em;
- top: 1.25em;
- left: 50%;
- margin-left: 1.5em\9;
- z-index: -1;
- }
-
- .progressDefine>li:last-child:after {
- display: none;
- }
-
- .progressDefine>li.is-complete {
- color: #4dc5cf;
- }
-
- .progressDefine>li.is-complete:before,
- .progressDefine>li.is-complete:after {
- color: #FFF;
- background: #4dc5cf;
- }
-
- .progressDefine>li.is-active {
- color: #3498DB;
- }
-
- .progressDefine>li.is-active:before {
- color: #FFF;
- background: #3498DB;
- }
- /**
- * Needed for IE8
- */
-
- .progressDefine__last:after {
- display: none !important;
- }
- /**
- * Size Extensions
- */
-
- .progressDefine--medium {
- font-size: 1.5em;
- }
-
- .progressDefine--large {
- font-size: 2em;
- }
- /**
- * Some Generic Stylings
- */
-
- *,
- *:after,
- *:before {
- box-sizing: border-box;
- }
-
- h1 {
- margin-bottom: 1.5em;
- }
-
- .progressDefine {
- margin-bottom: 3em;
- }
-
- a {
- color: #3498DB;
- text-decoration: none;
- }
-
- a:hover {
- text-decoration: underline;
- }
- /*
- body {
- text-align: center;
- color: #444;
- }*/
-</style>
diff --git a/nsb_setup.sh b/nsb_setup.sh
index 88027d9bd..cc2542989 100755
--- a/nsb_setup.sh
+++ b/nsb_setup.sh
@@ -28,7 +28,7 @@ if [ "$(whoami)" != "root" ]; then
fi
INSTALL_BIN_PATH="/opt/nsb_bin"
-TREX_VERSION="v2.20"
+TREX_VERSION="v2.28"
TREX_DOWNLOAD="https://trex-tgn.cisco.com/trex/release/$TREX_VERSION.tar.gz"
DPDK_DOWNLOAD="http://dpdk.org/browse/dpdk/snapshot/dpdk-16.07.zip"
VIRTUAL_VENV="$INSTALL_BIN_PATH/yardstick_venv"
@@ -202,6 +202,12 @@ push_nsb_binary()
cp "$REPO_DIR/yardstick/network_services/nfvi/collectd.sh" "$INSTALL_BIN_PATH"
cp "$REPO_DIR/yardstick/network_services/nfvi/collectd.conf" "$INSTALL_BIN_PATH"
cp "$REPO_DIR/nsb_setup.sh" "$INSTALL_BIN_PATH"
+
+ # Get "dpdk-devbind.py" to find the ports for VNF to run
+ wget http://dpdk.org/browse/dpdk/plain/usertools/dpdk-devbind.py?h=v17.05 -O dpdk-devbind.py
+ chmod 777 dpdk-devbind.py
+ mv dpdk-devbind.py "$INSTALL_BIN_PATH"
+ ln "$INSTALL_BIN_PATH"/dpdk-devbind.py "$INSTALL_BIN_PATH"/dpdk_nic_bind.py
echo "Done"
}
diff --git a/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_1b_Requests-65000_Concurrency.yaml b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_1b_Requests-65000_Concurrency.yaml
index 134722681..d4a4bb706 100644
--- a/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_1b_Requests-65000_Concurrency.yaml
+++ b/samples/vnf_samples/nsut/vfw/tc_baremetal_http_ixload_1b_Requests-65000_Concurrency.yaml
@@ -37,4 +37,4 @@ context:
type: Node
name: yardstick
nfvi_type: baremetal
- file: /etc/yardstick/nodes/pod.yaml
+ file: /etc/yardstick/nodes/pod_ixia.yaml
diff --git a/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_ixia.yaml b/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_ixia.yaml
index 746023de2..71a803d32 100644
--- a/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_ixia.yaml
+++ b/samples/vnf_samples/nsut/vfw/tc_baremetal_rfc2544_ipv4_1rule_1flow_64B_ixia.yaml
@@ -41,4 +41,4 @@ context:
type: Node
name: yardstick
nfvi_type: baremetal
- file: /etc/yardstick/nodes/pod.yaml
+ file: /etc/yardstick/nodes/pod_ixia.yaml
diff --git a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml
index ccd40c33b..6b213a54a 100644
--- a/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml
+++ b/samples/vnf_samples/traffic_profiles/ixia_ipv4_latency.yaml
@@ -53,6 +53,8 @@ private_1:
outer_l4:
srcport: "{{get(flow, 'flow.srcport_range', '1234') }}"
dstport: "{{get(flow, 'flow.dstport_range', '2001') }}"
+ count: "{{get(flow, 'flow.count', '1') }}"
+
public_1:
ipv4:
outer_l2:
@@ -75,6 +77,7 @@ public_1:
outer_l4:
srcport: "{{get(flow, 'flow.srcport_range', '1234') }}"
dstport: "{{get(flow, 'flow.dstport_range', '2001') }}"
+ count: "{{get(flow, 'flow.count', '1') }}"
private_2:
ipv4:
outer_l2:
@@ -97,6 +100,7 @@ private_2:
outer_l4:
srcport: "{{get(flow, 'flow.srcport_range', '1234') }}"
dstport: "{{get(flow, 'flow.dstport_range', '2001') }}"
+ count: "{{get(flow, 'flow.count', '1') }}"
public_2:
ipv4:
outer_l2:
@@ -119,3 +123,4 @@ public_2:
outer_l4:
srcport: "{{get(flow, 'flow.srcport_range', '1234') }}"
dstport: "{{get(flow, 'flow.dstport_range', '2001') }}"
+ count: "{{get(flow, 'flow.count', '1') }}"
diff --git a/tests/ci/apexlake-verify b/tests/ci/apexlake-verify
deleted file mode 100755
index 6a691063f..000000000
--- a/tests/ci/apexlake-verify
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-##############################################################################
-# Copyright (c) 2015 Ericsson AB and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-DPDK_HOST=10.118.36.130
-
-YARDSTICK=/home/user/yardstick
-TESTSUITE=$YARDSTICK/tests/opnfv/test_suites/opnfv_vTC_daily.yaml
-
-: ${INSTALLER_TYPE:='unknown'}
-: ${NODE_NAME:='unknown'}
-: ${DEPLOY_SCENARIO:='unknown'}
-
-commands="
-cd $YARDSTICK
-source /home/user/openrc.dasm
-export INSTALLER_TYPE=$INSTALLER_TYPE
-export NODE_NAME=$NODE_NAME
-export DEPLOY_SCENARIO=$DEPLOY_SCENARIO
-sudo -E yardstick task start --suite $TESTSUITE"
-
-echo "$commands" | ssh -l user $DPDK_HOST 'bash -s'
-exit $?
diff --git a/tests/unit/benchmark/contexts/standalone/__init__.py b/tests/unit/benchmark/contexts/standalone/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/unit/benchmark/contexts/standalone/__init__.py
diff --git a/tests/unit/benchmark/contexts/ovs_sample_password.yaml b/tests/unit/benchmark/contexts/standalone/ovs_sample_password.yaml
index b1da1ea9f..b1da1ea9f 100644
--- a/tests/unit/benchmark/contexts/ovs_sample_password.yaml
+++ b/tests/unit/benchmark/contexts/standalone/ovs_sample_password.yaml
diff --git a/tests/unit/benchmark/contexts/ovs_sample_ssh_key.yaml b/tests/unit/benchmark/contexts/standalone/ovs_sample_ssh_key.yaml
index 896ec33bb..896ec33bb 100644
--- a/tests/unit/benchmark/contexts/ovs_sample_ssh_key.yaml
+++ b/tests/unit/benchmark/contexts/standalone/ovs_sample_ssh_key.yaml
diff --git a/tests/unit/benchmark/contexts/ovs_sample_write_to_file.txt b/tests/unit/benchmark/contexts/standalone/ovs_sample_write_to_file.txt
index f0eec86f6..f0eec86f6 100644
--- a/tests/unit/benchmark/contexts/ovs_sample_write_to_file.txt
+++ b/tests/unit/benchmark/contexts/standalone/ovs_sample_write_to_file.txt
diff --git a/tests/unit/benchmark/contexts/sriov_sample_password.yaml b/tests/unit/benchmark/contexts/standalone/sriov_sample_password.yaml
index 4f60e46d5..4f60e46d5 100644
--- a/tests/unit/benchmark/contexts/sriov_sample_password.yaml
+++ b/tests/unit/benchmark/contexts/standalone/sriov_sample_password.yaml
diff --git a/tests/unit/benchmark/contexts/sriov_sample_ssh_key.yaml b/tests/unit/benchmark/contexts/standalone/sriov_sample_ssh_key.yaml
index faa496771..faa496771 100644
--- a/tests/unit/benchmark/contexts/sriov_sample_ssh_key.yaml
+++ b/tests/unit/benchmark/contexts/standalone/sriov_sample_ssh_key.yaml
diff --git a/tests/unit/benchmark/contexts/sriov_sample_write_to_file.txt b/tests/unit/benchmark/contexts/standalone/sriov_sample_write_to_file.txt
index f0eec86f6..f0eec86f6 100644
--- a/tests/unit/benchmark/contexts/sriov_sample_write_to_file.txt
+++ b/tests/unit/benchmark/contexts/standalone/sriov_sample_write_to_file.txt
diff --git a/tests/unit/benchmark/contexts/test_ovsdpdk.py b/tests/unit/benchmark/contexts/standalone/test_ovsdpdk.py
index ac25ec877..1d68384c9 100644
--- a/tests/unit/benchmark/contexts/test_ovsdpdk.py
+++ b/tests/unit/benchmark/contexts/standalone/test_ovsdpdk.py
@@ -13,11 +13,13 @@
# limitations under the License.
from __future__ import absolute_import
+
import os
-import mock
import unittest
-from yardstick.benchmark.contexts import ovsdpdk
+import mock
+
+from yardstick.benchmark.contexts.standalone import ovsdpdk
NIC_INPUT = {
'interface': {},
@@ -226,11 +228,11 @@ class OvsdpdkTestCase(unittest.TestCase):
mock_ovs = mock.Mock()
ssh_mock.put = mock.Mock()
ovs_obj.check_output = mock.Mock(return_value=(0, "vm1"))
- with mock.patch("yardstick.benchmark.contexts.ovsdpdk.time"):
+ with mock.patch("yardstick.benchmark.contexts.standalone.ovsdpdk.time"):
self.assertIsNone(ovs_obj.setup_ovs_context(PCIS, NIC_DETAILS, DRIVER))
@mock.patch(
- 'yardstick.benchmark.contexts.ovsdpdk',
+ 'yardstick.benchmark.contexts.standalone.ovsdpdk',
return_value="Domain vm1 created from /tmp/vm_ovs.xml")
def test_is_vm_created(self, NIC_INPUT):
with mock.patch("yardstick.ssh.SSH") as ssh:
diff --git a/tests/unit/benchmark/contexts/test_sriov.py b/tests/unit/benchmark/contexts/standalone/test_sriov.py
index a8641a2eb..ea72e1bab 100644
--- a/tests/unit/benchmark/contexts/test_sriov.py
+++ b/tests/unit/benchmark/contexts/standalone/test_sriov.py
@@ -13,11 +13,13 @@
# limitations under the License.
from __future__ import absolute_import
+
import os
-import mock
import unittest
-from yardstick.benchmark.contexts import sriov
+import mock
+
+from yardstick.benchmark.contexts.standalone import sriov
NIC_INPUT = {
'interface': {},
@@ -185,7 +187,7 @@ class SriovTestCase(unittest.TestCase):
nic_details['vf_pci'][i] = sriov_obj.get_vf_datas.return_value
vf_pci = [[], []]
vf_pci[i] = sriov_obj.get_vf_datas.return_value
- with mock.patch("yardstick.benchmark.contexts.sriov.time"):
+ with mock.patch("yardstick.benchmark.contexts.standalone.sriov.time"):
self.assertIsNotNone(sriov_obj.configure_nics_for_sriov(DRIVER, NIC_DETAILS))
def test_setup_sriov_context(self):
@@ -224,7 +226,7 @@ class SriovTestCase(unittest.TestCase):
mock.Mock(return_value=(0, {}, ""))
ssh_mock.put = mock.Mock()
sriov_obj.check_output = mock.Mock(return_value=(1, {}))
- with mock.patch("yardstick.benchmark.contexts.sriov.time"):
+ with mock.patch("yardstick.benchmark.contexts.standalone.sriov.time"):
self.assertIsNone(sriov_obj.setup_sriov_context(PCIS, nic_details, DRIVER))
def test_setup_sriov_context_vm_already_present(self):
@@ -263,11 +265,11 @@ class SriovTestCase(unittest.TestCase):
mock.Mock(return_value=(0, {}, ""))
ssh_mock.put = mock.Mock()
sriov_obj.check_output = mock.Mock(return_value=(0, "vm1"))
- with mock.patch("yardstick.benchmark.contexts.sriov.time"):
+ with mock.patch("yardstick.benchmark.contexts.standalone.sriov.time"):
self.assertIsNone(sriov_obj.setup_sriov_context(PCIS, nic_details, DRIVER))
@mock.patch(
- 'yardstick.benchmark.contexts.sriov',
+ 'yardstick.benchmark.contexts.standalone.sriov',
return_value="Domain vm1 created from /tmp/vm_sriov.xml")
def test_is_vm_created(self, NIC_INPUT):
with mock.patch("yardstick.ssh.SSH") as ssh:
diff --git a/tests/unit/benchmark/contexts/test_standalone.py b/tests/unit/benchmark/contexts/test_standalone.py
index d13e28470..b1402a1c9 100644
--- a/tests/unit/benchmark/contexts/test_standalone.py
+++ b/tests/unit/benchmark/contexts/test_standalone.py
@@ -18,25 +18,26 @@
# Unittest for yardstick.benchmark.contexts.standalone
from __future__ import absolute_import
+
import os
import unittest
+
import mock
from yardstick.benchmark.contexts import standalone
-from yardstick.benchmark.contexts import sriov
-from yardstick.benchmark.contexts import ovsdpdk
+from yardstick.benchmark.contexts.standalone import ovsdpdk, sriov
MOCKS = {
'yardstick.benchmark.contexts': mock.MagicMock(),
- 'yardstick.benchmark.contexts.sriov': mock.MagicMock(),
- 'yardstick.benchmark.contexts.ovsdpdk': mock.MagicMock(),
+ 'yardstick.benchmark.contexts.standalone.sriov': mock.MagicMock(),
+ 'yardstick.benchmark.contexts.standalone.ovsdpdk': mock.MagicMock(),
'yardstick.benchmark.contexts.standalone': mock.MagicMock(),
}
-@mock.patch('yardstick.benchmark.contexts.ovsdpdk.time')
+@mock.patch('yardstick.benchmark.contexts.standalone.ovsdpdk.time')
@mock.patch('yardstick.benchmark.contexts.standalone.time')
-@mock.patch('yardstick.benchmark.contexts.sriov.time')
+@mock.patch('yardstick.benchmark.contexts.standalone.sriov.time')
class StandaloneContextTestCase(unittest.TestCase):
NODES_SAMPLE = "nodes_sample_new.yaml"
NODES_SAMPLE_SRIOV = "nodes_sample_new_sriov.yaml"
@@ -564,7 +565,7 @@ class StandaloneContextTestCase(unittest.TestCase):
self.assertIsNone(self.test_context.undeploy())
def test_get_nfvi_obj_sriov(self, mock_sriov_time, mock_standlalone_time, mock_ovsdpdk_time):
- with mock.patch('yardstick.benchmark.contexts.sriov'):
+ with mock.patch('yardstick.benchmark.contexts.standalone.sriov'):
attrs = {
'name': 'sriov',
'file': self._get_file_abspath(self.NODES_SAMPLE)
@@ -589,7 +590,7 @@ class StandaloneContextTestCase(unittest.TestCase):
self.assertIsNotNone(self.test_context.get_nfvi_obj())
def test_get_nfvi_obj_ovs(self, mock_sriov_time, mock_standlalone_time, mock_ovsdpdk_time):
- with mock.patch('yardstick.benchmark.contexts.ovsdpdk'):
+ with mock.patch('yardstick.benchmark.contexts.standalone.ovsdpdk'):
attrs = {
'name': 'ovs',
'file': self._get_file_abspath(self.NODES_SAMPLE_OVSDPDK)
diff --git a/tests/unit/benchmark/core/test_task.py b/tests/unit/benchmark/core/test_task.py
index 25688bf48..14027e43c 100644
--- a/tests/unit/benchmark/core/test_task.py
+++ b/tests/unit/benchmark/core/test_task.py
@@ -290,8 +290,9 @@ class TaskTestCase(unittest.TestCase):
task.change_server_name(scenario, suffix)
self.assertTrue(scenario['target']['name'], 'demo-8')
+ @mock.patch('yardstick.benchmark.core.task.utils')
@mock.patch('yardstick.benchmark.core.task.logging')
- def test_set_log(self, mock_logging):
+ def test_set_log(self, mock_logging, mock_utils):
task_obj = task.Task()
task_obj.task_id = 'task_id'
task_obj._set_log()
diff --git a/tests/unit/benchmark/scenarios/lib/test_attach_volume.py b/tests/unit/benchmark/scenarios/lib/test_attach_volume.py
new file mode 100644
index 000000000..e69924072
--- /dev/null
+++ b/tests/unit/benchmark/scenarios/lib/test_attach_volume.py
@@ -0,0 +1,33 @@
+##############################################################################
+# 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
+##############################################################################
+import unittest
+import mock
+
+from yardstick.benchmark.scenarios.lib.attach_volume import AttachVolume
+
+
+class AttachVolumeTestCase(unittest.TestCase):
+
+ @mock.patch('yardstick.common.openstack_utils.attach_server_volume')
+ def test_attach_volume(self, mock_attach_server_volume):
+ options = {
+ 'volume_id': '123-456-000',
+ 'server_id': '000-123-456'
+ }
+ args = {"options": options}
+ obj = AttachVolume(args, {})
+ obj.run({})
+ self.assertTrue(mock_attach_server_volume.called)
+
+def main():
+ unittest.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/unit/benchmark/scenarios/lib/test_create_floating_ip.py b/tests/unit/benchmark/scenarios/lib/test_create_floating_ip.py
new file mode 100644
index 000000000..72dbcd7cd
--- /dev/null
+++ b/tests/unit/benchmark/scenarios/lib/test_create_floating_ip.py
@@ -0,0 +1,34 @@
+##############################################################################
+# 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
+##############################################################################
+import unittest
+import mock
+
+from yardstick.benchmark.scenarios.lib.create_floating_ip import CreateFloatingIp
+
+
+class CreateFloatingIpTestCase(unittest.TestCase):
+
+ @mock.patch('yardstick.common.openstack_utils.create_floating_ip')
+ @mock.patch('yardstick.common.openstack_utils.get_network_id')
+ @mock.patch('yardstick.common.openstack_utils.get_neutron_client')
+ def test_create_floating_ip(self, mock_create_floating_ip, mock_get_network_id, mock_get_neutron_client):
+ options = {}
+ args = {"options": options}
+ obj = CreateFloatingIp(args, {})
+ obj.run({})
+ self.assertTrue(mock_create_floating_ip.called)
+ self.assertTrue(mock_get_network_id.called)
+ self.assertTrue(mock_get_neutron_client.called)
+
+def main():
+ unittest.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/unit/benchmark/scenarios/lib/test_create_keypair.py b/tests/unit/benchmark/scenarios/lib/test_create_keypair.py
new file mode 100644
index 000000000..99e6b9afa
--- /dev/null
+++ b/tests/unit/benchmark/scenarios/lib/test_create_keypair.py
@@ -0,0 +1,35 @@
+##############################################################################
+# 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
+##############################################################################
+import unittest
+import mock
+import paramiko
+
+from yardstick.benchmark.scenarios.lib.create_keypair import CreateKeypair
+
+
+class CreateKeypairTestCase(unittest.TestCase):
+
+ @mock.patch('yardstick.common.openstack_utils.create_keypair')
+ def test_create_keypair(self, mock_create_keypair):
+ options = {
+ 'key_name': 'yardstick_key',
+ 'key_path': '/tmp/yardstick_key'
+ }
+ args = {"options": options}
+ obj = CreateKeypair(args, {})
+ obj.run({})
+ self.assertTrue(mock_create_keypair.called)
+
+
+def main():
+ unittest.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/unit/benchmark/scenarios/lib/test_get_numa_info.py b/tests/unit/benchmark/scenarios/lib/test_get_numa_info.py
index e7ba3ca73..680692fdc 100644
--- a/tests/unit/benchmark/scenarios/lib/test_get_numa_info.py
+++ b/tests/unit/benchmark/scenarios/lib/test_get_numa_info.py
@@ -18,7 +18,7 @@ class GetNumaInfoTestCase(unittest.TestCase):
@mock.patch('{}.GetNumaInfo._check_numa_node'.format(BASE))
@mock.patch('{}.GetNumaInfo._get_current_host_name'.format(BASE))
- @mock.patch('yaml.safe_load')
+ @mock.patch('yardstick.benchmark.scenarios.lib.get_numa_info.yaml_load')
@mock.patch('yardstick.common.task_template.TaskTemplate.render')
def test_get_numa_info(self,
mock_render,
@@ -44,7 +44,7 @@ class GetNumaInfoTestCase(unittest.TestCase):
@mock.patch('yardstick.ssh.SSH.from_node')
@mock.patch('{}.GetNumaInfo._get_current_host_name'.format(BASE))
- @mock.patch('yaml.safe_load')
+ @mock.patch('yardstick.benchmark.scenarios.lib.get_numa_info.yaml_load')
@mock.patch('yardstick.common.task_template.TaskTemplate.render')
def test_check_numa_node(self,
mock_render,
@@ -74,7 +74,7 @@ class GetNumaInfoTestCase(unittest.TestCase):
@mock.patch('{}.change_obj_to_dict'.format(BASE))
@mock.patch('{}.get_nova_client'.format(BASE))
- @mock.patch('yaml.safe_load')
+ @mock.patch('yardstick.benchmark.scenarios.lib.get_numa_info.yaml_load')
@mock.patch('yardstick.common.task_template.TaskTemplate.render')
def test_get_current_host_name(self,
mock_render,
diff --git a/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py b/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py
index 84b42c832..651614d3e 100644
--- a/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py
+++ b/tests/unit/benchmark/scenarios/networking/test_vnf_generic.py
@@ -26,7 +26,7 @@ import mock
from yardstick.benchmark.scenarios.networking.vnf_generic import \
SshManager, NetworkServiceTestCase, IncorrectConfig, \
- IncorrectSetup, open_relative_file
+ open_relative_file
from yardstick.network_services.collector.subscriber import Collector
from yardstick.network_services.vnf_generic.vnf.base import \
GenericTrafficGen, GenericVNF
@@ -471,7 +471,7 @@ class TestNetworkServiceTestCase(unittest.TestCase):
mock.Mock(return_value=(1, SYS_CLASS_NET + IP_ADDR_SHOW, ""))
ssh.from_node.return_value = ssh_mock
- with self.assertRaises(IncorrectSetup):
+ with self.assertRaises(IncorrectConfig):
self.s.map_topology_to_infrastructure()
def test_map_topology_to_infrastructure_config_invalid(self):
@@ -694,11 +694,11 @@ class TestNetworkServiceTestCase(unittest.TestCase):
def test_probe_missing_values(self):
netdevs = self.SAMPLE_NETDEVS.copy()
network = {'local_mac': '0a:de:ad:be:ef:f5'}
- NetworkServiceTestCase._probe_missing_values(netdevs, network, set())
+ NetworkServiceTestCase._probe_missing_values(netdevs, network)
assert network['vpci'] == '0000:0b:00.0'
network = {'local_mac': '0a:de:ad:be:ef:f4'}
- NetworkServiceTestCase._probe_missing_values(netdevs, network, set())
+ NetworkServiceTestCase._probe_missing_values(netdevs, network)
assert network['vpci'] == '0000:00:19.0'
def test_open_relative_path(self):
diff --git a/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py b/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py
index 3b9f99b08..de5bae2f3 100644
--- a/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py
+++ b/tests/unit/benchmark/scenarios/networking/test_vsperf_dpdk.py
@@ -28,8 +28,6 @@ from yardstick.benchmark.scenarios.networking import vsperf_dpdk
@mock.patch('yardstick.benchmark.scenarios.networking.vsperf_dpdk.subprocess')
@mock.patch('yardstick.benchmark.scenarios.networking.vsperf_dpdk.ssh')
-@mock.patch("yardstick.benchmark.scenarios.networking.vsperf_dpdk.open",
- mock.mock_open())
class VsperfDPDKTestCase(unittest.TestCase):
def setUp(self):
diff --git a/tests/unit/common/test_utils.py b/tests/unit/common/test_utils.py
index 663226242..923ec4aaa 100644
--- a/tests/unit/common/test_utils.py
+++ b/tests/unit/common/test_utils.py
@@ -20,6 +20,7 @@ from itertools import product, chain
import mock
from six.moves import configparser
+import yardstick
from yardstick.common import utils
from yardstick.common import constants
@@ -45,47 +46,25 @@ class IterSubclassesTestCase(unittest.TestCase):
self.assertEqual([B, C, D], list(utils.itersubclasses(A)))
-class TryAppendModuleTestCase(unittest.TestCase):
-
- @mock.patch('yardstick.common.utils.importutils')
- def test_try_append_module_not_in_modules(self, mock_importutils):
-
- modules = {}
- name = 'foo'
- utils.try_append_module(name, modules)
- mock_importutils.import_module.assert_called_with(name)
-
- @mock.patch('yardstick.common.utils.importutils')
- def test_try_append_module_already_in_modules(self, mock_importutils):
-
- modules = {'foo'}
- name = 'foo'
- utils.try_append_module(name, modules)
- self.assertFalse(mock_importutils.import_module.called)
-
-
class ImportModulesFromPackageTestCase(unittest.TestCase):
@mock.patch('yardstick.common.utils.os.walk')
- @mock.patch('yardstick.common.utils.try_append_module')
- def test_import_modules_from_package_no_mod(self, mock_append, mock_walk):
-
- sep = os.sep
+ def test_import_modules_from_package_no_mod(self, mock_walk):
+ yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__))
mock_walk.return_value = ([
- ('..' + sep + 'foo', ['bar'], ['__init__.py']),
- ('..' + sep + 'foo' + sep + 'bar', [], ['baz.txt', 'qux.rst'])
+ (os.path.join(yardstick_root, 'foo'), ['bar'], ['__init__.py']),
+ (os.path.join(yardstick_root, 'foo', 'bar'), [], ['baz.txt', 'qux.rst'])
])
utils.import_modules_from_package('foo.bar')
- self.assertFalse(mock_append.called)
@mock.patch('yardstick.common.utils.os.walk')
@mock.patch('yardstick.common.utils.importutils')
def test_import_modules_from_package(self, mock_importutils, mock_walk):
- sep = os.sep
+ yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__))
mock_walk.return_value = ([
- ('foo' + sep + '..' + sep + 'bar', [], ['baz.py'])
+ (os.path.join(yardstick_root, 'foo', os.pardir, 'bar'), [], ['baz.py'])
])
utils.import_modules_from_package('foo.bar')
diff --git a/tests/unit/common/test_yaml_loader.py b/tests/unit/common/test_yaml_loader.py
new file mode 100644
index 000000000..90cbb8157
--- /dev/null
+++ b/tests/unit/common/test_yaml_loader.py
@@ -0,0 +1,32 @@
+# 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.
+
+# yardstick: this file is copied from python-heatclient and slightly modified
+
+from __future__ import absolute_import
+import unittest
+
+from yardstick.common import yaml_loader
+
+
+class TemplateFormatTestCase(unittest.TestCase):
+
+ def test_parse_to_value_exception(self):
+
+ self.assertEquals(yaml_loader.yaml_load("string"), u"string")
+
+
+def main():
+ unittest.main()
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/unit/network_services/libs/ixia_libs/test_IxNet.py b/tests/unit/network_services/libs/ixia_libs/test_IxNet.py
index 9114b5163..ae4c58de1 100644
--- a/tests/unit/network_services/libs/ixia_libs/test_IxNet.py
+++ b/tests/unit/network_services/libs/ixia_libs/test_IxNet.py
@@ -32,19 +32,14 @@ class TestIxNextgen(unittest.TestCase):
ixnet_gen = IxNextgen()
self.assertIsNone(ixnet_gen._bidir)
- @mock.patch("yardstick.network_services.libs.ixia_libs.IxNet.IxNet.IxNetwork")
@mock.patch("yardstick.network_services.libs.ixia_libs.IxNet.IxNet.sys")
- def test_connect(self, mock_sys, mock_ix_network):
- mock_ix_network.IxNet.return_value = mock_ixnet = mock.Mock()
+ def test_connect(self, mock_sys):
ixnet_gen = IxNextgen()
ixnet_gen.get_config = mock.MagicMock()
ixnet_gen.get_ixnet = mock.MagicMock()
- result = ixnet_gen._connect({"py_lib_path": "/tmp"})
- self.assertIsNotNone(result)
- self.assertEqual(mock_ix_network.IxNet.call_count, 1)
- self.assertEqual(mock_ixnet.connect.call_count, 1)
+ self.assertRaises(ImportError, ixnet_gen._connect, {"py_lib_path": "/tmp"})
def test_clear_ixia_config(self):
ixnet = mock.MagicMock()
@@ -263,7 +258,7 @@ class TestIxNextgen(unittest.TestCase):
result = ixnet_gen.ix_get_statistics()
self.assertIsNotNone(result)
- self.assertEqual(ixnet.getList.call_count, 2)
+ self.assertEqual(ixnet.getList.call_count, 1)
self.assertEqual(ixnet.execute.call_count, 20)
def test_find_view_obj_no_where(self):
@@ -455,7 +450,7 @@ class TestIxNextgen(unittest.TestCase):
}
ixnet = mock.MagicMock()
- ixnet.remapIds.return_value=["0"]
+ ixnet.remapIds.return_value = ["0"]
ixnet.setMultiAttribute.return_value = [1]
ixnet.commit.return_value = [1]
ixnet.getList.side_effect = [[1], [0, 1], [0], ["srcIp", "dstIp"]]
@@ -865,7 +860,7 @@ class TestIxNextgen(unittest.TestCase):
ixnet = mock.MagicMock()
ixnet.setMultiAttribute.return_value = [1]
ixnet.commit.return_value = [1]
- ixnet.getList.side_effect=[
+ ixnet.getList.side_effect = [
[1],
[1],
[1],
diff --git a/tests/unit/network_services/nfvi/test_resource.py b/tests/unit/network_services/nfvi/test_resource.py
index cb26fd085..072f06edf 100644
--- a/tests/unit/network_services/nfvi/test_resource.py
+++ b/tests/unit/network_services/nfvi/test_resource.py
@@ -108,13 +108,13 @@ class TestResourceProfile(unittest.TestCase):
def test_get_cpu_data(self):
reskey = ["", "cpufreq", "cpufreq-0"]
value = "metric:10"
- val = self.resource_profile.get_cpu_data(reskey, value)
+ val = self.resource_profile.get_cpu_data(reskey[1], reskey[2], value)
self.assertIsNotNone(val)
def test_get_cpu_data_error(self):
reskey = ["", "", ""]
value = "metric:10"
- val = self.resource_profile.get_cpu_data(reskey, value)
+ val = self.resource_profile.get_cpu_data(reskey[0], reskey[1], value)
self.assertEqual(val, ('error', 'Invalid', '', ''))
def test__start_collectd(self):
diff --git a/tests/unit/network_services/test_yang_model.py b/tests/unit/network_services/test_yang_model.py
index 28367f316..0b29da701 100644
--- a/tests/unit/network_services/test_yang_model.py
+++ b/tests/unit/network_services/test_yang_model.py
@@ -95,7 +95,7 @@ class YangModelTestCase(unittest.TestCase):
y._get_entries()
self.assertEqual(y._rules, '')
- @mock.patch('yaml.safe_load')
+ @mock.patch('yardstick.network_services.yang_model.yaml_load')
@mock.patch('yardstick.network_services.yang_model.open')
def test__read_config(self, mock_open, mock_safe_load):
cfg = "yang.yaml"
diff --git a/tests/unit/network_services/traffic_profile/test_http_ixload.py b/tests/unit/network_services/traffic_profile/test_http_ixload.py
index 2e1b6f4ff..5110439fd 100644
--- a/tests/unit/network_services/traffic_profile/test_http_ixload.py
+++ b/tests/unit/network_services/traffic_profile/test_http_ixload.py
@@ -16,11 +16,33 @@
from __future__ import absolute_import
import unittest
import mock
-import runpy
from oslo_serialization import jsonutils
from yardstick.network_services.traffic_profile import http_ixload
+from yardstick.network_services.traffic_profile.http_ixload import \
+ join_non_strings, validate_non_string_sequence
+
+
+class TestJoinNonStrings(unittest.TestCase):
+
+ def test_validate_non_string_sequence(self):
+ self.assertEqual(validate_non_string_sequence([1, 2, 3]), [1, 2, 3])
+ self.assertIsNone(validate_non_string_sequence('123'))
+ self.assertIsNone(validate_non_string_sequence(1))
+
+ self.assertEqual(validate_non_string_sequence(1, 2), 2)
+ self.assertEqual(validate_non_string_sequence(1, default=2), 2)
+
+ with self.assertRaises(RuntimeError):
+ validate_non_string_sequence(1, raise_exc=RuntimeError)
+
+ def test_join_non_strings(self):
+ self.assertEqual(join_non_strings(':'), '')
+ self.assertEqual(join_non_strings(':', 'a'), 'a')
+ self.assertEqual(join_non_strings(':', 'a', 2, 'c'), 'a:2:c')
+ self.assertEqual(join_non_strings(':', ['a', 2, 'c']), 'a:2:c')
+ self.assertEqual(join_non_strings(':', 'abc'), 'abc')
class TestIxLoadTrafficGen(unittest.TestCase):
diff --git a/tests/unit/network_services/vnf_generic/test_vnfdgen.py b/tests/unit/network_services/vnf_generic/test_vnfdgen.py
index be51e4a43..c2b923568 100644
--- a/tests/unit/network_services/vnf_generic/test_vnfdgen.py
+++ b/tests/unit/network_services/vnf_generic/test_vnfdgen.py
@@ -21,6 +21,7 @@ from __future__ import absolute_import
import unittest
from six.moves import range
+from yardstick.common.yaml_loader import yaml_load
from yardstick.network_services.vnf_generic import vnfdgen
TREX_VNFD_TEMPLATE = """
@@ -65,6 +66,8 @@ vnfd:vnfd-catalog:
dst_mac: '{{ interfaces.xe1.dst_mac }}'
bandwidth: 10 Gbps
vnfd-connection-point-ref: xe1
+ routing_table: {{ routing_table }}
+ nd_route_tbl: {{ nd_route_tbl }}
benchmark:
kpi:
@@ -126,6 +129,22 @@ COMPLETE_TREX_VNFD = \
'vpci': '0000:00:10.1'},
'vnfd-connection-point-ref': 'xe1'}],
'id': 'trexgen-baremetal',
+ 'nd_route_tbl': [{'gateway': '0064:ff9b:0:0:0:0:9810:6414',
+ 'if': 'xe0',
+ 'netmask': '112',
+ 'network': '0064:ff9b:0:0:0:0:9810:6414'},
+ {'gateway': '0064:ff9b:0:0:0:0:9810:2814',
+ 'if': 'xe1',
+ 'netmask': '112',
+ 'network': '0064:ff9b:0:0:0:0:9810:2814'}],
+ 'routing_table': [{'gateway': '152.16.100.20',
+ 'if': 'xe0',
+ 'netmask': '255.255.255.0',
+ 'network': '152.16.100.20'},
+ {'gateway': '152.16.40.20',
+ 'if': 'xe1',
+ 'netmask': '255.255.255.0',
+ 'network': '152.16.40.20'}],
'name': 'trexgen-baremetal'}]}]}}
NODE_CFG = {'ip': '1.1.1.1',
@@ -144,7 +163,24 @@ NODE_CFG = {'ip': '1.1.1.1',
'dst_mac': '00:01:02:03:04:06',
'local_ip': '2.1.1.2',
'local_mac': '00:01:02:03:05:06',
- 'vpci': '0000:00:10.1'}}}
+ 'vpci': '0000:00:10.1'}},
+ 'nd_route_tbl': [{u'gateway': u'0064:ff9b:0:0:0:0:9810:6414',
+ u'if': u'xe0',
+ u'netmask': u'112',
+ u'network': u'0064:ff9b:0:0:0:0:9810:6414'},
+ {u'gateway': u'0064:ff9b:0:0:0:0:9810:2814',
+ u'if': u'xe1',
+ u'netmask': u'112',
+ u'network': u'0064:ff9b:0:0:0:0:9810:2814'}],
+ 'routing_table': [{u'gateway': u'152.16.100.20',
+ u'if': u'xe0',
+ u'netmask': u'255.255.255.0',
+ u'network': u'152.16.100.20'},
+ {u'gateway': u'152.16.40.20',
+ u'if': u'xe1',
+ u'netmask': u'255.255.255.0',
+ u'network': u'152.16.40.20'}],
+ }
TRAFFIC_PROFILE_TPL = """
@@ -169,6 +205,20 @@ TRAFFIC_PROFILE = {
"1518B": '40'}}}}]}
+class TestRender(unittest.TestCase):
+
+ def test_render_none(self):
+
+ tmpl = "{{ routing_table }}"
+ self.assertEqual(vnfdgen.render(tmpl, routing_table=None), u'~')
+ self.assertEqual(yaml_load(vnfdgen.render(tmpl, routing_table=None)), None)
+
+ def test_render_unicode_dict(self):
+
+ tmpl = "{{ routing_table }}"
+ self.assertEqual(yaml_load(vnfdgen.render(tmpl, **NODE_CFG)), NODE_CFG["routing_table"])
+
+
class TestVnfdGen(unittest.TestCase):
""" Class to verify VNFS testcases """
@@ -193,6 +243,14 @@ class TestVnfdGen(unittest.TestCase):
d = {'a': 1, 'b': 2}
self.assertEqual(vnfdgen.deepgetitem(d, "a"), 1)
+ def test_dict_flatten_str_int_key_first(self):
+ d = {'0': 1, 0: 24, 'b': 2}
+ self.assertEqual(vnfdgen.deepgetitem(d, "0"), 1)
+
+ def test_dict_flatten_int_key_fallback(self):
+ d = {0: 1, 'b': 2}
+ self.assertEqual(vnfdgen.deepgetitem(d, "0"), 1)
+
def test_dict_flatten_list(self):
d = {'a': 1, 'b': list(range(2))}
self.assertEqual(vnfdgen.deepgetitem(d, "b.0"), 0)
@@ -201,6 +259,11 @@ class TestVnfdGen(unittest.TestCase):
d = {'a': 1, 'b': {x: x for x in list(range(2))}}
self.assertEqual(vnfdgen.deepgetitem(d, "b.0"), 0)
+ def test_dict_flatten_only_str_key(self):
+ d = {'0': 1, 0: 24, 'b': 2}
+ self.assertRaises(AttributeError, vnfdgen.deepgetitem, d, 0)
+
+
def test_generate_tp_single_var(self):
""" Function to verify traffic profile generation with imix """
diff --git a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py
index af0d2ddde..07a862a8e 100644
--- a/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py
+++ b/tests/unit/network_services/vnf_generic/vnf/test_sample_vnf.py
@@ -1142,7 +1142,7 @@ class TestClientResourceHelper(unittest.TestCase):
}
@mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.LOG')
- @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLStateError',
+ @mock.patch('yardstick.network_services.vnf_generic.vnf.sample_vnf.STLError',
new_callable=lambda: MockError)
def test_get_stats_not_connected(self, mock_state_error, mock_logger):
vnfd_helper = VnfdHelper({})
diff --git a/yardstick/benchmark/contexts/node.py b/yardstick/benchmark/contexts/node.py
index 35c64335d..250032efc 100644
--- a/yardstick/benchmark/contexts/node.py
+++ b/yardstick/benchmark/contexts/node.py
@@ -17,12 +17,12 @@ import tempfile
import six
import pkg_resources
-import yaml
from yardstick import ssh
from yardstick.benchmark.contexts.base import Context
from yardstick.common.constants import ANSIBLE_DIR, YARDSTICK_ROOT_PATH
from yardstick.common.ansible_common import AnsibleCommon
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -55,7 +55,7 @@ class NodeContext(Context):
with open(self.file_path) as stream:
LOG.info("Parsing pod file: %s", self.file_path)
- cfg = yaml.safe_load(stream)
+ cfg = yaml_load(stream)
return cfg
def init(self, attrs):
diff --git a/yardstick/benchmark/contexts/standalone.py b/yardstick/benchmark/contexts/standalone/__init__.py
index ae1046974..f0ef1d560 100644
--- a/yardstick/benchmark/contexts/standalone.py
+++ b/yardstick/benchmark/contexts/standalone/__init__.py
@@ -18,12 +18,12 @@ import logging
import os
import errno
import collections
-import yaml
import time
from yardstick.benchmark.contexts.base import Context
from yardstick.common.constants import YARDSTICK_ROOT_PATH
from yardstick.common.utils import import_modules_from_package, itersubclasses
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -50,7 +50,7 @@ class StandaloneContext(Context):
with open(self.file_path) as stream:
LOG.info("Parsing pod file: %s", self.file_path)
- cfg = yaml.safe_load(stream)
+ cfg = yaml_load(stream)
return cfg
def get_nfvi_obj(self):
diff --git a/yardstick/benchmark/contexts/ovsdpdk.py b/yardstick/benchmark/contexts/standalone/ovsdpdk.py
index cf5529d89..cf5529d89 100644
--- a/yardstick/benchmark/contexts/ovsdpdk.py
+++ b/yardstick/benchmark/contexts/standalone/ovsdpdk.py
diff --git a/yardstick/benchmark/contexts/sriov.py b/yardstick/benchmark/contexts/standalone/sriov.py
index fe27d2579..fe27d2579 100644
--- a/yardstick/benchmark/contexts/sriov.py
+++ b/yardstick/benchmark/contexts/standalone/sriov.py
diff --git a/yardstick/benchmark/core/plugin.py b/yardstick/benchmark/core/plugin.py
index a741d5e74..24f1b6b25 100644
--- a/yardstick/benchmark/core/plugin.py
+++ b/yardstick/benchmark/core/plugin.py
@@ -13,13 +13,13 @@ from __future__ import print_function
from __future__ import absolute_import
import os
import sys
-import yaml
import time
import logging
import pkg_resources
import yardstick.ssh as ssh
from yardstick.common.task_template import TaskTemplate
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -153,7 +153,7 @@ class PluginParser(object):
raise e
print("Input plugin is:\n%s\n" % rendered_plugin)
- cfg = yaml.safe_load(rendered_plugin)
+ cfg = yaml_load(rendered_plugin)
except IOError as ioerror:
sys.exit(ioerror)
diff --git a/yardstick/benchmark/core/task.py b/yardstick/benchmark/core/task.py
index ea3239edf..2c67e736c 100644
--- a/yardstick/benchmark/core/task.py
+++ b/yardstick/benchmark/core/task.py
@@ -29,6 +29,7 @@ from jinja2 import Environment
from yardstick.benchmark.contexts.base import Context
from yardstick.benchmark.runners import base as base_runner
+from yardstick.common.yaml_loader import yaml_load
from yardstick.dispatcher.base import Base as DispatcherBase
from yardstick.common.task_template import TaskTemplate
from yardstick.common.utils import source_env
@@ -172,6 +173,7 @@ class Task(object): # pragma: no cover
log_format = '%(asctime)s %(name)s %(filename)s:%(lineno)d %(levelname)s %(message)s'
log_formatter = logging.Formatter(log_format)
+ utils.makedirs(constants.TASK_LOG_DIR)
log_path = os.path.join(constants.TASK_LOG_DIR, '{}.log'.format(self.task_id))
log_handler = logging.FileHandler(log_path)
log_handler.setFormatter(log_formatter)
@@ -437,7 +439,7 @@ class TaskParser(object): # pragma: no cover
try:
with open(self.path) as stream:
- cfg = yaml.load(stream)
+ cfg = yaml_load(stream)
except IOError as ioerror:
sys.exit(ioerror)
@@ -501,7 +503,7 @@ class TaskParser(object): # pragma: no cover
raise e
print("Input task is:\n%s\n" % rendered_task)
- cfg = yaml.load(rendered_task)
+ cfg = yaml_load(rendered_task)
except IOError as ioerror:
sys.exit(ioerror)
@@ -657,7 +659,7 @@ def parse_task_args(src_name, args):
return args
try:
- kw = args and yaml.safe_load(args)
+ kw = args and yaml_load(args)
kw = {} if kw is None else kw
except yaml.parser.ParserError as e:
print_invalid_header(src_name, args)
diff --git a/yardstick/benchmark/core/testcase.py b/yardstick/benchmark/core/testcase.py
index 7ab1b08cf..501356726 100644
--- a/yardstick/benchmark/core/testcase.py
+++ b/yardstick/benchmark/core/testcase.py
@@ -12,11 +12,11 @@ from __future__ import absolute_import
from __future__ import print_function
import os
-import yaml
import logging
from yardstick.common.task_template import TaskTemplate
from yardstick.common import constants as consts
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -69,7 +69,7 @@ class Testcase(object):
def _parse_testcase(self, testcase_info):
rendered_testcase = TaskTemplate.render(testcase_info)
- testcase_cfg = yaml.safe_load(rendered_testcase)
+ testcase_cfg = yaml_load(rendered_testcase)
test_precondition = testcase_cfg.get('precondition', {})
installer_type = test_precondition.get('installer_type', 'all')
diff --git a/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py b/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py
index a20b26396..61698da43 100644
--- a/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py
+++ b/yardstick/benchmark/scenarios/availability/attacker/baseattacker.py
@@ -8,11 +8,11 @@
##############################################################################
from __future__ import absolute_import
import pkg_resources
-import yaml
import logging
import os
import yardstick.common.utils as utils
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -56,7 +56,7 @@ class BaseAttacker(object):
def __init__(self, config, context):
if not BaseAttacker.attacker_cfgs:
with open(attacker_conf_path) as stream:
- BaseAttacker.attacker_cfgs = yaml.safe_load(stream)
+ BaseAttacker.attacker_cfgs = yaml_load(stream)
self._config = config
self._context = context
diff --git a/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py b/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py
index 6165aba74..0027925d6 100644
--- a/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py
+++ b/yardstick/benchmark/scenarios/availability/monitor/basemonitor.py
@@ -13,7 +13,8 @@ import multiprocessing
import time
import os
import yardstick.common.utils as utils
-import yaml
+
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -74,7 +75,7 @@ class BaseMonitor(multiprocessing.Process):
def __init__(self, config, context, data):
if not BaseMonitor.monitor_cfgs:
with open(monitor_conf_path) as stream:
- BaseMonitor.monitor_cfgs = yaml.safe_load(stream)
+ BaseMonitor.monitor_cfgs = yaml_load(stream)
multiprocessing.Process.__init__(self)
self._config = config
self._context = context
diff --git a/yardstick/benchmark/scenarios/availability/operation/baseoperation.py b/yardstick/benchmark/scenarios/availability/operation/baseoperation.py
index 4c2ce82d9..d21b857b5 100644
--- a/yardstick/benchmark/scenarios/availability/operation/baseoperation.py
+++ b/yardstick/benchmark/scenarios/availability/operation/baseoperation.py
@@ -8,11 +8,11 @@
##############################################################################
from __future__ import absolute_import
import pkg_resources
-import yaml
import logging
import os
import yardstick.common.utils as utils
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -54,7 +54,7 @@ class BaseOperation(object):
def __init__(self, config, context):
if not BaseOperation.operation_cfgs:
with open(operation_conf_path) as stream:
- BaseOperation.operation_cfgs = yaml.safe_load(stream)
+ BaseOperation.operation_cfgs = yaml_load(stream)
self.key = ''
self._config = config
self._context = context
diff --git a/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py b/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py
index ce34d8be0..05b660105 100644
--- a/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py
+++ b/yardstick/benchmark/scenarios/availability/result_checker/baseresultchecker.py
@@ -8,11 +8,11 @@
##############################################################################
from __future__ import absolute_import
import pkg_resources
-import yaml
import logging
import os
import yardstick.common.utils as utils
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -58,7 +58,7 @@ class BaseResultChecker(object):
def __init__(self, config, context):
if not BaseResultChecker.resultchecker_cfgs:
with open(resultchecker_conf_path) as stream:
- BaseResultChecker.resultchecker_cfgs = yaml.safe_load(stream)
+ BaseResultChecker.resultchecker_cfgs = yaml_load(stream)
self.actualResult = object()
self.expectedResult = object()
self.success = False
diff --git a/yardstick/benchmark/scenarios/lib/attach_volume.py b/yardstick/benchmark/scenarios/lib/attach_volume.py
new file mode 100644
index 000000000..88124964b
--- /dev/null
+++ b/yardstick/benchmark/scenarios/lib/attach_volume.py
@@ -0,0 +1,53 @@
+##############################################################################
+# 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 __future__ import print_function
+from __future__ import absolute_import
+
+import logging
+
+from yardstick.benchmark.scenarios import base
+import yardstick.common.openstack_utils as op_utils
+
+LOG = logging.getLogger(__name__)
+
+
+class AttachVolume(base.Scenario):
+ """Attach a volmeu to an instance"""
+
+ __scenario_type__ = "AttachVolume"
+
+ def __init__(self, scenario_cfg, context_cfg):
+ self.scenario_cfg = scenario_cfg
+ self.context_cfg = context_cfg
+ self.options = self.scenario_cfg['options']
+
+ self.server_id = self.options.get("server_id", "TestServer")
+ self.volume_id = self.options.get("volume_id", None)
+
+ self.setup_done = False
+
+ def setup(self):
+ """scenario setup"""
+
+ self.setup_done = True
+
+ def run(self, result):
+ """execute the test"""
+
+ if not self.setup_done:
+ self.setup()
+
+ status = op_utils.attach_server_volume(self.server_id,
+ self.volume_id)
+
+ if status:
+ LOG.info("Attach volume to server successful!")
+ else:
+ LOG.info("Attach volume to server failed!")
diff --git a/yardstick/benchmark/scenarios/lib/create_floating_ip.py b/yardstick/benchmark/scenarios/lib/create_floating_ip.py
new file mode 100644
index 000000000..328566d48
--- /dev/null
+++ b/yardstick/benchmark/scenarios/lib/create_floating_ip.py
@@ -0,0 +1,60 @@
+##############################################################################
+# 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 __future__ import print_function
+from __future__ import absolute_import
+
+import logging
+import os
+
+from yardstick.benchmark.scenarios import base
+import yardstick.common.openstack_utils as op_utils
+
+LOG = logging.getLogger(__name__)
+
+
+class CreateFloatingIp(base.Scenario):
+ """Create an OpenStack floating ip"""
+
+ __scenario_type__ = "CreateFloatingIp"
+
+ def __init__(self, scenario_cfg, context_cfg):
+ self.scenario_cfg = scenario_cfg
+ self.context_cfg = context_cfg
+ self.ext_net_id = os.getenv("EXTERNAL_NETWORK", "external")
+
+ self.neutron_client = op_utils.get_neutron_client()
+ self.setup_done = False
+
+ def setup(self):
+ """scenario setup"""
+
+ self.setup_done = True
+
+ def run(self, result):
+ """execute the test"""
+
+ if not self.setup_done:
+ self.setup()
+
+ net_id = op_utils.get_network_id(self.neutron_client, self.ext_net_id)
+ floating_info = op_utils.create_floating_ip(self.neutron_client,
+ extnet_id=net_id)
+ if floating_info:
+ LOG.info("Creating floating ip successful!")
+ else:
+ LOG.error("Creating floating ip failed!")
+
+ try:
+ keys = self.scenario_cfg.get('output', '').split()
+ except KeyError:
+ pass
+ else:
+ values = [floating_info["fip_id"], floating_info["fip_addr"]]
+ return self._push_to_outputs(keys, values)
diff --git a/yardstick/benchmark/scenarios/lib/create_keypair.py b/yardstick/benchmark/scenarios/lib/create_keypair.py
new file mode 100644
index 000000000..5610de651
--- /dev/null
+++ b/yardstick/benchmark/scenarios/lib/create_keypair.py
@@ -0,0 +1,69 @@
+##############################################################################
+# 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 __future__ import print_function
+from __future__ import absolute_import
+
+import logging
+import paramiko
+
+from yardstick.benchmark.scenarios import base
+import yardstick.common.openstack_utils as op_utils
+
+LOG = logging.getLogger(__name__)
+
+
+class CreateKeypair(base.Scenario):
+ """Create an OpenStack keypair"""
+
+ __scenario_type__ = "CreateKeypair"
+
+ def __init__(self, scenario_cfg, context_cfg):
+ self.scenario_cfg = scenario_cfg
+ self.context_cfg = context_cfg
+ self.options = self.scenario_cfg['options']
+
+ self.key_name = self.options.get("key_name", "yardstick_key")
+ self.key_filename = self.options.get("key_path", "/tmp/yardstick_key")
+
+ self.setup_done = False
+
+ def setup(self):
+ """scenario setup"""
+
+ self.setup_done = True
+
+ def run(self, result):
+ """execute the test"""
+
+ if not self.setup_done:
+ self.setup()
+
+ rsa_key = paramiko.RSAKey.generate(bits=2048, progress_func=None)
+ rsa_key.write_private_key_file(self.key_filename)
+ print("Writing %s ..." % self.key_filename)
+ with open(self.key_filename + ".pub", "w") as pubkey_file:
+ pubkey_file.write(
+ "%s %s\n" % (rsa_key.get_name(), rsa_key.get_base64()))
+ del rsa_key
+
+ keypair = op_utils.create_keypair(self.key_name,
+ self.key_filename + ".pub")
+
+ if keypair:
+ LOG.info("Create keypair successful!")
+ else:
+ LOG.info("Create keypair failed!")
+ try:
+ keys = self.scenario_cfg.get('output', '').split()
+ except KeyError:
+ pass
+ else:
+ values = [keypair.id]
+ return self._push_to_outputs(keys, values)
diff --git a/yardstick/benchmark/scenarios/lib/get_numa_info.py b/yardstick/benchmark/scenarios/lib/get_numa_info.py
index 4e4a44d95..75a9e3506 100644
--- a/yardstick/benchmark/scenarios/lib/get_numa_info.py
+++ b/yardstick/benchmark/scenarios/lib/get_numa_info.py
@@ -13,7 +13,6 @@ from __future__ import absolute_import
import logging
import os
-import yaml
from xml.etree import ElementTree as ET
from yardstick import ssh
@@ -22,6 +21,7 @@ from yardstick.common import constants as consts
from yardstick.common.utils import change_obj_to_dict
from yardstick.common.openstack_utils import get_nova_client
from yardstick.common.task_template import TaskTemplate
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
@@ -47,7 +47,7 @@ class GetNumaInfo(base.Scenario):
self.options.get('file'))
with open(node_file) as f:
- nodes = yaml.safe_load(TaskTemplate.render(f.read()))
+ nodes = yaml_load(TaskTemplate.render(f.read()))
self.nodes = {a['host_name']: a for a in nodes['nodes']}
def run(self, result):
diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py
index 092e9a067..dcc372b8d 100644
--- a/yardstick/benchmark/scenarios/networking/vnf_generic.py
+++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py
@@ -21,12 +21,12 @@ import os
import re
from itertools import chain
-import yaml
from operator import itemgetter
from collections import defaultdict
from yardstick.benchmark.scenarios import base
from yardstick.common.utils import import_modules_from_package, itersubclasses
+from yardstick.common.yaml_loader import yaml_load
from yardstick.network_services.collector.subscriber import Collector
from yardstick.network_services.vnf_generic import vnfdgen
from yardstick.network_services.vnf_generic.vnf.base import GenericVNF
@@ -119,7 +119,7 @@ class NetworkServiceTestCase(base.Scenario):
# fixme: create schema to validate all fields have been provided
with open_relative_file(scenario_cfg["topology"],
scenario_cfg['task_path']) as stream:
- topology_yaml = yaml.safe_load(stream)
+ topology_yaml = yaml_load(stream)
self.topology = topology_yaml["nsd:nsd-catalog"]["nsd"][0]
self.vnfs = []
@@ -129,7 +129,7 @@ class NetworkServiceTestCase(base.Scenario):
def _get_traffic_flow(self):
try:
with open(self.scenario_cfg["traffic_options"]["flow"]) as fflow:
- flow = yaml.safe_load(fflow)
+ flow = yaml_load(fflow)
except (KeyError, IOError, OSError):
flow = {}
return flow
@@ -137,7 +137,7 @@ class NetworkServiceTestCase(base.Scenario):
def _get_traffic_imix(self):
try:
with open(self.scenario_cfg["traffic_options"]["imix"]) as fimix:
- imix = yaml.safe_load(fimix)
+ imix = yaml_load(fimix)
except (KeyError, IOError, OSError):
imix = {}
return imix
@@ -265,8 +265,25 @@ class NetworkServiceTestCase(base.Scenario):
for dpdk_port_num, netdev in enumerate(s):
netdev['dpdk_port_num'] = dpdk_port_num
+ def _probe_netdevs(self, node, node_dict):
+ cmd = "PATH=$PATH:/sbin:/usr/sbin ip addr show"
+ netdevs = {}
+ with SshManager(node_dict) as conn:
+ if conn:
+ exit_status = conn.execute(cmd)[0]
+ if exit_status != 0:
+ raise IncorrectSetup("Node's %s lacks ip tool." % node)
+ exit_status, stdout, _ = conn.execute(
+ self.FIND_NETDEVICE_STRING)
+ if exit_status != 0:
+ raise IncorrectSetup(
+ "Cannot find netdev info in sysfs" % node)
+ netdevs = node_dict['netdevs'] = self.parse_netdev_info(stdout)
+ return netdevs
+
@classmethod
- def _probe_missing_values(cls, netdevs, network, missing):
+ def _probe_missing_values(cls, netdevs, network):
+
mac_lower = network['local_mac'].lower()
for netdev in netdevs.values():
if netdev['address'].lower() != mac_lower:
@@ -288,36 +305,30 @@ class NetworkServiceTestCase(base.Scenario):
"""
for node, node_dict in self.context_cfg["nodes"].items():
- cmd = "PATH=$PATH:/sbin:/usr/sbin ip addr show"
- with SshManager(node_dict) as conn:
- exit_status = conn.execute(cmd)[0]
- if exit_status != 0:
- raise IncorrectSetup("Node's %s lacks ip tool." % node)
- exit_status, stdout, _ = conn.execute(
- self.FIND_NETDEVICE_STRING)
- if exit_status != 0:
- raise IncorrectSetup(
- "Cannot find netdev info in sysfs" % node)
- netdevs = node_dict['netdevs'] = self.parse_netdev_info(
- stdout)
-
- for network in node_dict["interfaces"].values():
- missing = self.TOPOLOGY_REQUIRED_KEYS.difference(network)
- if not missing:
- continue
-
- try:
- self._probe_missing_values(netdevs, network,
- missing)
- except KeyError:
- pass
- else:
- missing = self.TOPOLOGY_REQUIRED_KEYS.difference(
- network)
- if missing:
- raise IncorrectConfig(
- "Require interface fields '%s' not found, topology file "
- "corrupted" % ', '.join(missing))
+ for network in node_dict["interfaces"].values():
+ missing = self.TOPOLOGY_REQUIRED_KEYS.difference(network)
+ if not missing:
+ continue
+
+ # only ssh probe if there are missing values
+ # ssh probe won't work on Ixia, so we had better define all our values
+ try:
+ netdevs = self._probe_netdevs(node, node_dict)
+ except (SSHError, SSHTimeout):
+ raise IncorrectConfig(
+ "Unable to probe missing interface fields '%s', on node %s "
+ "SSH Error" % (', '.join(missing), node))
+ try:
+ self._probe_missing_values(netdevs, network)
+ except KeyError:
+ pass
+ else:
+ missing = self.TOPOLOGY_REQUIRED_KEYS.difference(
+ network)
+ if missing:
+ raise IncorrectConfig(
+ "Require interface fields '%s' not found, topology file "
+ "corrupted" % ', '.join(missing))
# 3. Use topology file to find connections & resolve dest address
self._resolve_topology()
diff --git a/yardstick/common/html_template.py b/yardstick/common/html_template.py
index f030a2f6c..e17c76637 100644
--- a/yardstick/common/html_template.py
+++ b/yardstick/common/html_template.py
@@ -158,7 +158,7 @@ report_template = """
<th>value</th>
</tr>
<tbody>
- {% for key, value in result.info.iteritems() %}
+ {% for key, value in result.info.items() %}
<tr>
<td>{{ loop.index }}</td>
<td>{{key}}</td>
@@ -177,7 +177,7 @@ report_template = """
<th>value</th>
</tr>
<tbody>
- {% for key, value in result.testcases.iteritems() %}
+ {% for key, value in result.testcases.items() %}
<tr>
<td>{{ loop.index }}</td>
<td>{{key}}</td>
diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py
index d86aee1cd..540d8d641 100644
--- a/yardstick/common/openstack_utils.py
+++ b/yardstick/common/openstack_utils.py
@@ -264,6 +264,15 @@ def create_aggregate_with_host(nova_client, aggregate_name, av_zone,
return True
+def create_keypair(nova_client, name, key_path=None): # pragma: no cover
+ try:
+ with open(key_path) as fpubkey:
+ keypair = get_nova_client().keypairs.create(name=name, public_key=fpubkey.read())
+ return keypair
+ except Exception:
+ log.exception("Error [create_keypair(nova_client)]")
+
+
def create_instance(json_body): # pragma: no cover
try:
return get_nova_client().servers.create(**json_body)
@@ -290,6 +299,17 @@ def create_instance_and_wait_for_active(json_body): # pragma: no cover
return None
+def attach_server_volume(server_id, volume_id, device=None): # pragma: no cover
+ try:
+ get_nova_client().volumes.create_server_volume(server_id, volume_id, device)
+ except Exception:
+ log.exception("Error [attach_server_volume(nova_client, '%s', '%s')]",
+ server_id, volume_id)
+ return False
+ else:
+ return True
+
+
def delete_instance(nova_client, instance_id): # pragma: no cover
try:
nova_client.servers.force_delete(instance_id)
@@ -417,6 +437,18 @@ def get_port_id_by_ip(neutron_client, ip_address): # pragma: no cover
'fixed_ips') if j['ip_address'] == ip_address), None)
+def create_floating_ip(neutron_client, extnet_id): # pragma: no cover
+ props = {'floating_network_id': extnet_id}
+ try:
+ ip_json = neutron_client.create_floatingip({'floatingip': props})
+ fip_addr = ip_json['floatingip']['floating_ip_address']
+ fip_id = ip_json['floatingip']['id']
+ except Exception:
+ log.error("Error [create_floating_ip(neutron_client)]")
+ return None
+ return {'fip_addr': fip_addr, 'fip_id': fip_id}
+
+
# *********************************************
# GLANCE
# *********************************************
diff --git a/yardstick/common/task_template.py b/yardstick/common/task_template.py
index 9acc21336..f6c128609 100755
--- a/yardstick/common/task_template.py
+++ b/yardstick/common/task_template.py
@@ -11,6 +11,22 @@ from __future__ import absolute_import
import re
import jinja2
import jinja2.meta
+import yaml
+
+
+def finalize_for_yaml(elem):
+ """Render Jinja2 output specifically for YAML files"""
+ # Jinaj2 by default converts None to 'None', we can't allow this
+ # we could convert to empty string '', or we can convert to null, aka ~
+ if elem is None:
+ return '~'
+ # convert data structures to inline YAML
+ # match builtin types because we shouldn't be trying to render complex types
+ if isinstance(elem, (dict, list)):
+ # remove newlines because we are injecting back into YAML
+ # use block style for single line
+ return yaml.safe_dump(elem, default_flow_style=True).replace('\n', '')
+ return elem
class TaskTemplate(object):
@@ -38,7 +54,7 @@ class TaskTemplate(object):
single_msg = ("Please specify template task argument:%s")
raise TypeError((len(real_missing) > 1 and multi_msg or single_msg)
% ", ".join(real_missing))
- return jinja2.Template(task_template).render(**kwargs)
+ return jinja2.Template(task_template, finalize=finalize_for_yaml).render(**kwargs)
def is_really_missing(mis, task_template):
diff --git a/yardstick/common/template_format.py b/yardstick/common/template_format.py
index 98c0a0b3c..bd5d8376f 100644
--- a/yardstick/common/template_format.py
+++ b/yardstick/common/template_format.py
@@ -18,9 +18,10 @@ import yaml
from oslo_serialization import jsonutils
if hasattr(yaml, 'CSafeLoader'):
- yaml_loader = yaml.CSafeLoader
+ # make a dynamic subclass so we don't override global yaml Loader
+ yaml_loader = type('HeatYamlLoader', (yaml.CSafeLoader,), {})
else:
- yaml_loader = yaml.SafeLoader
+ yaml_loader = type('HeatYamlLoader', (yaml.SafeLoader,), {})
if hasattr(yaml, 'CSafeDumper'):
yaml_dumper = yaml.CSafeDumper
@@ -28,10 +29,13 @@ else:
yaml_dumper = yaml.SafeDumper
+# This breaks NetworkServiceTestCase yaml loading, because we need to conversion to
+# native Python str() objects because we use use Trex and Trex is has broken unicode handling
def _construct_yaml_str(self, node):
# Override the default string handling function
# to always return unicode objects
return self.construct_scalar(node)
+
yaml_loader.add_constructor(u'tag:yaml.org,2002:str', _construct_yaml_str)
# Unquoted dates like 2013-05-23 in yaml files get loaded as objects of type
# datetime.data which causes problems in API layer when being processed by
diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py
index f2455be3a..1d7ea071c 100644
--- a/yardstick/common/utils.py
+++ b/yardstick/common/utils.py
@@ -30,7 +30,6 @@ import random
import ipaddress
from contextlib import closing
-import yaml
import six
from flask import jsonify
from six.moves import configparser
@@ -38,6 +37,7 @@ from oslo_utils import importutils
from oslo_serialization import jsonutils
import yardstick
+from yardstick.common.yaml_loader import yaml_load
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
@@ -70,26 +70,26 @@ def itersubclasses(cls, _seen=None):
yield sub
-def try_append_module(name, modules):
- if name not in modules:
- modules[name] = importutils.import_module(name)
-
-
def import_modules_from_package(package):
"""Import modules from package and append into sys.modules
:param: package - Full package name. For example: rally.deploy.engines
"""
- path = [os.path.dirname(yardstick.__file__), ".."] + package.split(".")
- path = os.path.join(*path)
+ yardstick_root = os.path.dirname(os.path.dirname(yardstick.__file__))
+ path = os.path.join(yardstick_root, *package.split("."))
for root, dirs, files in os.walk(path):
- for filename in files:
- if filename.startswith("__") or not filename.endswith(".py"):
- continue
- new_package = ".".join(root.split(os.sep)).split("....")[1]
- module_name = "%s.%s" % (new_package, filename[:-3])
+ matches = (filename for filename in files if filename.endswith(".py") and
+ not filename.startswith("__"))
+ new_package = os.path.relpath(root, yardstick_root).replace(os.sep, ".")
+ module_names = set(
+ ("{}.{}".format(new_package, filename.rsplit(".py", 1)[0]) for filename in matches))
+ # find modules which haven't already been imported
+ missing_modules = module_names.difference(sys.modules)
+ logger.debug("importing %s", missing_modules)
+ # we have already checked for already imported modules, so we don't need to check again
+ for module_name in missing_modules:
try:
- try_append_module(module_name, sys.modules)
+ sys.modules[module_name] = importutils.import_module(module_name)
except ImportError:
logger.exception("unable to import %s", module_name)
@@ -97,7 +97,7 @@ def import_modules_from_package(package):
def parse_yaml(file_path):
try:
with open(file_path) as f:
- value = yaml.safe_load(f)
+ value = yaml_load(f)
except IOError:
return {}
except OSError as e:
diff --git a/yardstick/common/yaml_loader.py b/yardstick/common/yaml_loader.py
new file mode 100644
index 000000000..0572bd582
--- /dev/null
+++ b/yardstick/common/yaml_loader.py
@@ -0,0 +1,33 @@
+# 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.
+
+# yardstick: this file is copied from python-heatclient and slightly modified
+
+from __future__ import absolute_import
+
+import yaml
+
+
+if hasattr(yaml, 'CSafeLoader'):
+ # make a dynamic subclass so we don't override global yaml Loader
+ yaml_loader = type('CustomLoader', (yaml.CSafeLoader,), {})
+else:
+ yaml_loader = type('CustomLoader', (yaml.SafeLoader,), {})
+
+if hasattr(yaml, 'CSafeDumper'):
+ yaml_dumper = yaml.CSafeDumper
+else:
+ yaml_dumper = yaml.SafeDumper
+
+
+def yaml_load(tmpl_str):
+ return yaml.load(tmpl_str, Loader=yaml_loader)
diff --git a/yardstick/network_services/helpers/samplevnf_helper.py b/yardstick/network_services/helpers/samplevnf_helper.py
index 1eefc5ffa..dbaa47c19 100644
--- a/yardstick/network_services/helpers/samplevnf_helper.py
+++ b/yardstick/network_services/helpers/samplevnf_helper.py
@@ -90,7 +90,7 @@ class MultiPortConfig(object):
def make_ip_addr(ip, mask_len):
try:
return ipaddress.ip_interface(six.text_type('/'.join([ip, mask_len])))
- except ValueError:
+ except (TypeError, ValueError):
# None so we can skip later
return None
@@ -499,7 +499,10 @@ class MultiPortConfig(object):
def get_route_data(self, src_key, data_key, port):
route_list = self.vnfd['vdu'][0].get(src_key, [])
- return next((route[data_key] for route in route_list if route['if'] == port), None)
+ try:
+ return next((route[data_key] for route in route_list if route['if'] == port), None)
+ except (TypeError, StopIteration, KeyError):
+ return None
def get_ports_gateway(self, port):
return self.get_route_data('routing_table', 'gateway', port)
diff --git a/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py b/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py
index 815a2a21c..2b8905b4f 100644
--- a/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py
+++ b/yardstick/network_services/libs/ixia_libs/IxNet/IxNet.py
@@ -20,13 +20,6 @@ import logging
import re
from itertools import product
-from yardstick.common.utils import ErrorClass
-
-try:
- import IxNetwork
-except ImportError:
- IxNetwork = ErrorClass
-
log = logging.getLogger(__name__)
IP_VERSION_4 = 4
@@ -203,6 +196,12 @@ class IxNextgen(object):
self._cfg = self.get_config(tg_cfg)
sys.path.append(self._cfg["py_lib_path"])
+ # Import IxNetwork after getting ixia lib path
+ try:
+ import IxNetwork
+ except ImportError:
+ raise
+
self.ixnet = IxNetwork.IxNet()
machine = self._cfg['machine']
@@ -322,13 +321,13 @@ class IxNextgen(object):
def ix_get_statistics(self):
views = self.ixnet.getList('/statistics', 'view')
+ stats = {}
view_obj = self.find_view_obj("Traffic Item Statistics", views)
stats = self.build_stats_map(view_obj, self.STATS_NAME_MAP)
- self.find_view_obj("Port Statistics", views)
+ view_obj = self.find_view_obj("Port Statistics", views)
ports_stats = self.build_stats_map(view_obj, self.PORT_STATS_NAME_MAP)
- views = self.ixnet.getList('/statistics', 'view')
view_obj = self.find_view_obj("Flow Statistics", views)
stats["latency"] = self.build_stats_map(view_obj, self.LATENCY_NAME_MAP)
diff --git a/yardstick/network_services/nfvi/resource.py b/yardstick/network_services/nfvi/resource.py
index ce09b6597..2fb4a8e8e 100644
--- a/yardstick/network_services/nfvi/resource.py
+++ b/yardstick/network_services/nfvi/resource.py
@@ -73,18 +73,18 @@ class ResourceProfile(object):
@classmethod
def parse_simple_resource(cls, key, value):
- return {'/'.join(key): value.split(":")[1]}
+ reskey = "/".join(rkey for rkey in key if "nsb_stats" not in rkey)
+ return {reskey: value.split(":")[1]}
@classmethod
- def get_cpu_data(cls, key_split, value):
+ def get_cpu_data(cls, res_key0, res_key1, value):
""" Get cpu topology of the host """
pattern = r"-(\d+)"
- if "cpufreq" in key_split[0]:
- metric = key_split[0]
- source = key_split[1]
+
+ if 'cpufreq' in res_key0:
+ metric, source = res_key0, res_key1
else:
- metric = key_split[1]
- source = key_split[0]
+ metric, source = res_key1, res_key0
match = re.search(pattern, source, re.MULTILINE)
if not match:
@@ -128,7 +128,8 @@ class ResourceProfile(object):
res_key1 = next(res_key_iter)
if "cpu" in res_key0 or "intel_rdt" in res_key0:
- cpu_key, name, metric, testcase = self.get_cpu_data(key_split, value)
+ cpu_key, name, metric, testcase = \
+ self.get_cpu_data(res_key0, res_key1, value)
if cpu_key in core_list:
result["cpu"].setdefault(cpu_key, {}).update({name: metric})
@@ -136,16 +137,16 @@ class ResourceProfile(object):
result["memory"].update({res_key1: value.split(":")[0]})
elif "hugepages" in res_key0:
- result["hugepages"].update(self.parse_hugepages(key, value))
+ result["hugepages"].update(self.parse_hugepages(key_split, value))
elif "dpdkstat" in res_key0:
- result["dpdkstat"].update(self.parse_dpdkstat(key, value))
+ result["dpdkstat"].update(self.parse_dpdkstat(key_split, value))
elif "virt" in res_key1:
- result["virt"].update(self.parse_virt(key, value))
+ result["virt"].update(self.parse_virt(key_split, value))
elif "ovs_stats" in res_key0:
- result["ovs_stats"].update(self.parse_ovs_stats(key, value))
+ result["ovs_stats"].update(self.parse_ovs_stats(key_split, value))
result["timestamp"] = testcase
@@ -153,13 +154,16 @@ class ResourceProfile(object):
def amqp_process_for_nfvi_kpi(self):
""" amqp collect and return nfvi kpis """
- if self.amqp_client is None:
+ if self.amqp_client is None and self.enable:
self.amqp_client = \
multiprocessing.Process(target=self.run_collectd_amqp)
self.amqp_client.start()
def amqp_collect_nfvi_kpi(self):
""" amqp collect and return nfvi kpis """
+ if not self.enable:
+ return {}
+
metric = {}
while not self._queue.empty():
metric.update(self._queue.get())
@@ -193,8 +197,6 @@ class ResourceProfile(object):
def _start_collectd(self, connection, bin_path):
LOG.debug("Starting collectd to collect NFVi stats")
- # temp disable
- return
connection.execute('sudo pkill -9 collectd')
collectd = os.path.join(bin_path, "collectd.sh")
provision_tool(connection, collectd)
diff --git a/yardstick/network_services/traffic_profile/http_ixload.py b/yardstick/network_services/traffic_profile/http_ixload.py
index 8a4f97f04..348056551 100644
--- a/yardstick/network_services/traffic_profile/http_ixload.py
+++ b/yardstick/network_services/traffic_profile/http_ixload.py
@@ -18,6 +18,7 @@ from __future__ import print_function
import sys
import os
import logging
+import collections
# ixload uses its own py2. So importing jsonutils fails. So adding below
# workaround to support call from yardstick
@@ -26,8 +27,16 @@ try:
except ImportError:
import json as jsonutils
-from yardstick.common.utils import join_non_strings
-from yardstick.common.utils import ErrorClass
+
+class ErrorClass(object):
+
+ def __init__(self, *args, **kwargs):
+ if 'test' not in kwargs:
+ raise RuntimeError
+
+ def __getattr__(self, item):
+ raise AttributeError
+
try:
from IxLoad import IxLoad, StatCollectorUtils
@@ -80,11 +89,25 @@ Incoming stats: Time interval: %s
"""
+def validate_non_string_sequence(value, default=None, raise_exc=None):
+ if isinstance(value, collections.Sequence) and not isinstance(value, str):
+ return value
+ if raise_exc:
+ raise raise_exc
+ return default
+
+
+def join_non_strings(separator, *non_strings):
+ try:
+ non_strings = validate_non_string_sequence(non_strings[0], raise_exc=RuntimeError)
+ except (IndexError, RuntimeError):
+ pass
+ return str(separator).join(str(non_string) for non_string in non_strings)
+
+
class IXLOADHttpTest(object):
def __init__(self, test_input):
- self.test_input = jsonutils.loads(test_input)
- self.parse_run_test()
self.ix_load = None
self.stat_utils = None
self.remote_server = None
@@ -94,6 +117,8 @@ class IXLOADHttpTest(object):
self.chassis = None
self.card = None
self.ports_to_reassign = None
+ self.test_input = jsonutils.loads(test_input)
+ self.parse_run_test()
@staticmethod
def format_ports_for_reassignment(ports):
@@ -291,4 +316,5 @@ def main(args):
ixload_obj.start_http_test()
if __name__ == '__main__':
+ LOG.info("Start http_ixload test")
main(sys.argv)
diff --git a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py
index 60979ebd2..0434f6aef 100644
--- a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py
+++ b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py
@@ -39,7 +39,7 @@ from yardstick.network_services.utils import get_nsb_option
from stl.trex_stl_lib.trex_stl_client import STLClient
from stl.trex_stl_lib.trex_stl_client import LoggerApi
-from stl.trex_stl_lib.trex_stl_exceptions import STLError, STLStateError
+from stl.trex_stl_lib.trex_stl_exceptions import STLError
from yardstick.ssh import AutoConnectSSH
@@ -457,7 +457,7 @@ class ClientResourceHelper(ResourceHelper):
def get_stats(self, *args, **kwargs):
try:
return self.client.get_stats(*args, **kwargs)
- except STLStateError:
+ except STLError:
LOG.exception("TRex client not connected")
return {}
@@ -497,18 +497,24 @@ class ClientResourceHelper(ResourceHelper):
def run_traffic(self, traffic_profile):
# fixme: fix passing correct trex config file,
# instead of searching the default path
- self._build_ports()
- self.client = self._connect()
- self.client.reset(ports=self.my_ports)
- self.client.remove_all_streams(self.my_ports) # remove all streams
- traffic_profile.register_generator(self)
-
- while self._terminated.value == 0:
- self._run_traffic_once(traffic_profile)
-
- self.client.stop(self.my_ports)
- self.client.disconnect()
- self._terminated.value = 0
+ try:
+ self._build_ports()
+ self.client = self._connect()
+ self.client.reset(ports=self.my_ports)
+ self.client.remove_all_streams(self.my_ports) # remove all streams
+ traffic_profile.register_generator(self)
+
+ while self._terminated.value == 0:
+ self._run_traffic_once(traffic_profile)
+
+ self.client.stop(self.my_ports)
+ self.client.disconnect()
+ self._terminated.value = 0
+ except STLError:
+ if self._terminated.value:
+ LOG.debug("traffic generator is stopped")
+ return # return if trex/tg server is stopped.
+ raise
def terminate(self):
self._terminated.value = 1 # stop client
@@ -925,6 +931,7 @@ class SampleVNFTrafficGen(GenericTrafficGen):
self._tg_process.start()
def wait_for_instantiate(self):
+ # overridden by subclasses
return self._wait_for_process()
def _check_status(self):
diff --git a/yardstick/network_services/vnf_generic/vnf/tg_ixload.py b/yardstick/network_services/vnf_generic/vnf/tg_ixload.py
index c15f7b954..353d31fc6 100644
--- a/yardstick/network_services/vnf_generic/vnf/tg_ixload.py
+++ b/yardstick/network_services/vnf_generic/vnf/tg_ixload.py
@@ -46,7 +46,7 @@ IXLOAD_CONFIG_TEMPLATE = '''\
},
"remote_server": "%s",
"result_dir": "%s",
- "ixload_cfg": '"C:/Results/%s"
+ "ixload_cfg": "C:/Results/%s"
}'''
IXLOAD_CMD = "{ixloadpy} {http_ixload} {args}"
@@ -122,7 +122,6 @@ class IxLoadTrafficGen(SampleVNFTrafficGen):
super(IxLoadTrafficGen, self).__init__(name, vnfd, setup_env_helper_type,
resource_helper_type)
self._result = {}
- self.done = False
self.data = None
def run_traffic(self, traffic_profile):
@@ -131,7 +130,7 @@ class IxLoadTrafficGen(SampleVNFTrafficGen):
for interface in self.vnfd_helper.interfaces:
vpci_list = interface['virtual-interface']["vpci"].split(":")
card = vpci_list[0]
- ports.append(vpci_list[1])
+ ports.append(str(vpci_list[1]))
for csv_file in glob.iglob(self.ssh_helper.join_bin_path('*.csv')):
os.unlink(csv_file)
@@ -143,6 +142,7 @@ class IxLoadTrafficGen(SampleVNFTrafficGen):
os.path.basename(self.resource_helper.resource_file_name))
http_ixload_path = os.path.join(VNF_PATH, "../../traffic_profile")
+
cmd = IXLOAD_CMD.format(
ixloadpy=os.path.join(ixia_config["py_bin_path"], "ixloadpython"),
http_ixload=os.path.join(http_ixload_path, "http_ixload.py"),
@@ -169,7 +169,10 @@ class IxLoadTrafficGen(SampleVNFTrafficGen):
def instantiate(self, scenario_cfg, context_cfg):
super(IxLoadTrafficGen, self).instantiate(scenario_cfg, context_cfg)
- self.done = False
+
+ def wait_for_instantiate(self):
+ # not needed for Ixload
+ pass
def terminate(self):
call(["pkill", "-9", "http_ixload.py"])
diff --git a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
index 07bbdae95..78d2bd8ba 100644
--- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
+++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py
@@ -23,11 +23,6 @@ from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTraff
from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
from yardstick.network_services.vnf_generic.vnf.sample_vnf import Rfc2544ResourceHelper
-try:
- from IxNet import IxNextgen
-except ImportError:
- IxNextgen = ErrorClass
-
LOG = logging.getLogger(__name__)
WAIT_AFTER_CFG_LOAD = 10
@@ -36,6 +31,11 @@ IXIA_LIB = os.path.dirname(os.path.realpath(__file__))
IXNET_LIB = os.path.join(IXIA_LIB, "../../libs/ixia_libs/IxNet")
sys.path.append(IXNET_LIB)
+try:
+ from IxNet import IxNextgen
+except ImportError:
+ IxNextgen = ErrorClass
+
class IxiaRfc2544Helper(Rfc2544ResourceHelper):
@@ -59,12 +59,12 @@ class IxiaResourceHelper(ClientResourceHelper):
self.pub_ports = None
def _connect(self, client=None):
- self.client.connect(self.vnfd_helper)
+ self.client._connect(self.vnfd_helper)
def _build_ports(self):
# self.generate_port_pairs(self.topology)
- self.priv_ports = [int(x[0][-1]) for x in self.tg_port_pairs]
- self.pub_ports = [int(x[1][-1]) for x in self.tg_port_pairs]
+ self.priv_ports = [int(x[0][2:]) for x in self.tg_port_pairs]
+ self.pub_ports = [int(x[1][2:]) for x in self.tg_port_pairs]
self.my_ports = list(set(self.priv_ports).union(set(self.pub_ports)))
def get_stats(self, *args, **kwargs):
@@ -72,7 +72,7 @@ class IxiaResourceHelper(ClientResourceHelper):
def stop_collect(self):
self._terminated.value = 0
- if self.client:
+ if self.client and self.client.ixnet:
self.client.ix_stop_traffic()
def generate_samples(self, key=None, default=None):
@@ -109,7 +109,7 @@ class IxiaResourceHelper(ClientResourceHelper):
self.client.ix_assign_ports()
mac = {}
- for index, interface in enumerate(self.vnfd_helper.interfaces):
+ for index, interface in enumerate(self.vnfd_helper.interfaces, 1):
virt_intf = interface["virtual-interface"]
mac.update({
"src_mac_{}".format(index): virt_intf["local_mac"],
@@ -163,3 +163,7 @@ class IxiaTrafficGen(SampleVNFTrafficGen):
def terminate(self):
self.resource_helper.stop_collect()
super(IxiaTrafficGen, self).terminate()
+
+ def wait_for_instantiate(self):
+ # not needed for IxNet
+ pass
diff --git a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py
index 79e42e0a8..d94a9a6e6 100644
--- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py
+++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_trex.py
@@ -52,11 +52,14 @@ class TrexRfcResourceHelper(TrexResourceHelper):
def _build_ports(self):
self.tg_port_pairs, self.networks = MultiPortConfig.get_port_pairs(
self.vnfd_helper.interfaces)
- self.priv_ports = [int(x[0][-1]) for x in self.tg_port_pairs]
- self.pub_ports = [int(x[1][-1]) for x in self.tg_port_pairs]
+ self.priv_ports = [int(x[0][2:]) for x in self.tg_port_pairs]
+ self.pub_ports = [int(x[1][2:]) for x in self.tg_port_pairs]
self.my_ports = list(set(chain(self.priv_ports, self.pub_ports)))
def _run_traffic_once(self, traffic_profile):
+ if self._terminated.value:
+ return
+
traffic_profile.execute(self)
self.client_started.value = 1
time.sleep(self.RUN_DURATION)
diff --git a/yardstick/network_services/vnf_generic/vnfdgen.py b/yardstick/network_services/vnf_generic/vnfdgen.py
index 0120b493e..f42635006 100644
--- a/yardstick/network_services/vnf_generic/vnfdgen.py
+++ b/yardstick/network_services/vnf_generic/vnfdgen.py
@@ -14,26 +14,29 @@
""" Generic file to map and build vnf discriptor """
from __future__ import absolute_import
+
from functools import reduce
import jinja2
import logging
-import yaml
+from yardstick.common.task_template import finalize_for_yaml
from yardstick.common.utils import try_int
+from yardstick.common.yaml_loader import yaml_load
LOG = logging.getLogger(__name__)
def render(vnf_model, **kwargs):
"""Render jinja2 VNF template
+ Do not check for missing arguments
:param vnf_model: string that contains template
:param kwargs: Dict with template arguments
:returns:rendered template str
"""
- return jinja2.Template(vnf_model).render(**kwargs)
+ return jinja2.Template(vnf_model, finalize=finalize_for_yaml).render(**kwargs)
def generate_vnfd(vnf_model, node):
@@ -54,7 +57,7 @@ def generate_vnfd(vnf_model, node):
rendered_vnfd = render(vnf_model, **node)
# This is done to get rid of issues with serializing node
del node["get"]
- filled_vnfd = yaml.safe_load(rendered_vnfd)
+ filled_vnfd = yaml_load(rendered_vnfd)
return filled_vnfd
@@ -73,19 +76,24 @@ def deepgetitem(obj, item, default=None):
add try_int to work with sequences
- >>> d = {'snl_final': {'about': {'_icsd': {'icsd_id': 1, 'fr': [2, 3]}}}}
+ >>> d = {'snl_final': {'about': {'_icsd': {'icsd_id': 1, 'fr': [2, 3], '0': 24, 0: 4}}}}
>>> deepgetitem(d, 'snl_final.about._icsd.icsd_id')
1
>>> deepgetitem(d, 'snl_final.about._sandbox.sbx_id')
>>>
>>> deepgetitem(d, 'snl_final.about._icsd.fr.1')
3
+ >>> deepgetitem(d, 'snl_final.about._icsd.0')
+ 24
"""
def getitem(obj, name):
- # if integer then list index
- name = try_int(name)
+ # try string then convert to int
try:
return obj[name]
except (KeyError, TypeError, IndexError):
- return default
+ name = try_int(name)
+ try:
+ return obj[name]
+ except (KeyError, TypeError, IndexError):
+ return default
return reduce(getitem, item.split('.'), obj)
diff --git a/yardstick/network_services/yang_model.py b/yardstick/network_services/yang_model.py
index fbf224bd8..ec00c4513 100644
--- a/yardstick/network_services/yang_model.py
+++ b/yardstick/network_services/yang_model.py
@@ -1,107 +1,108 @@
-# Copyright (c) 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.
-
-from __future__ import absolute_import
-from __future__ import print_function
-import logging
-import ipaddress
-import yaml
-import six
-
-LOG = logging.getLogger(__name__)
-
-
-class YangModel(object):
-
- RULE_TEMPLATE = "p acl add 1 {0} {1} {2} {3} {4} {5} {6} {7} 0 0 {8}"
-
- def __init__(self, config_file):
- super(YangModel, self).__init__()
- self._config_file = config_file
- self._options = {}
- self._rules = ''
-
- @property
- def config_file(self):
- return self._config_file
-
- @config_file.setter
- def config_file(self, value):
- self._config_file = value
- self._options = {}
- self._rules = ''
-
- def _read_config(self):
- # TODO: add some error handling in case of empty or non-existing file
- try:
- with open(self._config_file) as f:
- self._options = yaml.safe_load(f)
- except Exception as e:
- LOG.exception("Failed to load the yaml %s", e)
- raise
-
- def _get_entries(self):
- if not self._options:
- return ''
-
- rule_list = []
- for ace in self._options['access-list1']['acl']['access-list-entries']:
- # TODO: resolve ports using topology file and nodes'
- # ids: public or private.
- matches = ace['ace']['matches']
- dst_ipv4_net = matches['destination-ipv4-network']
- dst_ipv4_net_ip = ipaddress.ip_interface(six.text_type(dst_ipv4_net))
- port0_local_network = dst_ipv4_net_ip.network.network_address.exploded
- port0_prefix = dst_ipv4_net_ip.network.prefixlen
-
- src_ipv4_net = matches['source-ipv4-network']
- src_ipv4_net_ip = ipaddress.ip_interface(six.text_type(src_ipv4_net))
- port1_local_network = src_ipv4_net_ip.network.network_address.exploded
- port1_prefix = src_ipv4_net_ip.network.prefixlen
-
- lower_dport = matches['destination-port-range']['lower-port']
- upper_dport = matches['destination-port-range']['upper-port']
-
- lower_sport = matches['source-port-range']['lower-port']
- upper_sport = matches['source-port-range']['upper-port']
-
- # TODO: proto should be read from file also.
- # Now all rules in sample ACL file are TCP.
- rule_list.append('') # get an extra new line
- rule_list.append(self.RULE_TEMPLATE.format(port0_local_network,
- port0_prefix,
- port1_local_network,
- port1_prefix,
- lower_dport,
- upper_dport,
- lower_sport,
- upper_sport,
- 0))
- rule_list.append(self.RULE_TEMPLATE.format(port1_local_network,
- port1_prefix,
- port0_local_network,
- port0_prefix,
- lower_sport,
- upper_sport,
- lower_dport,
- upper_dport,
- 1))
-
- self._rules = '\n'.join(rule_list)
-
- def get_rules(self):
- if not self._rules:
- self._read_config()
- self._get_entries()
- return self._rules
+# Copyright (c) 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.
+
+from __future__ import absolute_import
+from __future__ import print_function
+import logging
+import ipaddress
+import six
+
+from yardstick.common.yaml_loader import yaml_load
+
+LOG = logging.getLogger(__name__)
+
+
+class YangModel(object):
+
+ RULE_TEMPLATE = "p acl add 1 {0} {1} {2} {3} {4} {5} {6} {7} 0 0 {8}"
+
+ def __init__(self, config_file):
+ super(YangModel, self).__init__()
+ self._config_file = config_file
+ self._options = {}
+ self._rules = ''
+
+ @property
+ def config_file(self):
+ return self._config_file
+
+ @config_file.setter
+ def config_file(self, value):
+ self._config_file = value
+ self._options = {}
+ self._rules = ''
+
+ def _read_config(self):
+ # TODO: add some error handling in case of empty or non-existing file
+ try:
+ with open(self._config_file) as f:
+ self._options = yaml_load(f)
+ except Exception as e:
+ LOG.exception("Failed to load the yaml %s", e)
+ raise
+
+ def _get_entries(self):
+ if not self._options:
+ return ''
+
+ rule_list = []
+ for ace in self._options['access-list1']['acl']['access-list-entries']:
+ # TODO: resolve ports using topology file and nodes'
+ # ids: public or private.
+ matches = ace['ace']['matches']
+ dst_ipv4_net = matches['destination-ipv4-network']
+ dst_ipv4_net_ip = ipaddress.ip_interface(six.text_type(dst_ipv4_net))
+ port0_local_network = dst_ipv4_net_ip.network.network_address.exploded
+ port0_prefix = dst_ipv4_net_ip.network.prefixlen
+
+ src_ipv4_net = matches['source-ipv4-network']
+ src_ipv4_net_ip = ipaddress.ip_interface(six.text_type(src_ipv4_net))
+ port1_local_network = src_ipv4_net_ip.network.network_address.exploded
+ port1_prefix = src_ipv4_net_ip.network.prefixlen
+
+ lower_dport = matches['destination-port-range']['lower-port']
+ upper_dport = matches['destination-port-range']['upper-port']
+
+ lower_sport = matches['source-port-range']['lower-port']
+ upper_sport = matches['source-port-range']['upper-port']
+
+ # TODO: proto should be read from file also.
+ # Now all rules in sample ACL file are TCP.
+ rule_list.append('') # get an extra new line
+ rule_list.append(self.RULE_TEMPLATE.format(port0_local_network,
+ port0_prefix,
+ port1_local_network,
+ port1_prefix,
+ lower_dport,
+ upper_dport,
+ lower_sport,
+ upper_sport,
+ 0))
+ rule_list.append(self.RULE_TEMPLATE.format(port1_local_network,
+ port1_prefix,
+ port0_local_network,
+ port0_prefix,
+ lower_sport,
+ upper_sport,
+ lower_dport,
+ upper_dport,
+ 1))
+
+ self._rules = '\n'.join(rule_list)
+
+ def get_rules(self):
+ if not self._rules:
+ self._read_config()
+ self._get_entries()
+ return self._rules