summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gui/app/images/logo.pngbin0 -> 4323 bytes
-rw-r--r--gui/app/scripts/controllers/report.controller.js2
-rw-r--r--gui/app/views/environmentList.html11
-rw-r--r--gui/app/views/layout/header.html9
-rw-r--r--gui/app/views/layout/sideNav.html2
-rw-r--r--gui/app/views/layout/sideNav2.html2
-rw-r--r--gui/app/views/main.html4
-rw-r--r--gui/app/views/main2.html4
-rw-r--r--gui/app/views/modal/environmentDialog.html6
-rw-r--r--gui/app/views/projectList.html8
-rw-r--r--gui/app/views/projectdetail.html10
-rw-r--r--gui/app/views/suite.html51
-rw-r--r--gui/app/views/testcaselist.html16
-rw-r--r--gui/bower.json3
-rwxr-xr-xinstall.sh1
-rwxr-xr-xrun_tests.sh3
-rw-r--r--samples/container_ping_vm.yaml57
-rw-r--r--samples/migrate-node-context.yaml40
-rw-r--r--tests/ci/cover.sh10
-rw-r--r--tests/opnfv/test_suites/opnfv_os-odl-sfc-ha_daily.yaml62
-rw-r--r--tests/unit/benchmark/scenarios/compute/test_qemumigrate.py166
-rw-r--r--yardstick/benchmark/scenarios/compute/qemu_migrate.py155
-rw-r--r--yardstick/benchmark/scenarios/compute/qemu_migrate_benchmark.bash68
-rwxr-xr-xyardstick/cmd/NSBperf.py7
-rw-r--r--yardstick/cmd/commands/task.py8
25 files changed, 638 insertions, 67 deletions
diff --git a/gui/app/images/logo.png b/gui/app/images/logo.png
new file mode 100644
index 000000000..c67c0d635
--- /dev/null
+++ b/gui/app/images/logo.png
Binary files differ
diff --git a/gui/app/scripts/controllers/report.controller.js b/gui/app/scripts/controllers/report.controller.js
index 9b6b5958b..6a62cf8ea 100644
--- a/gui/app/scripts/controllers/report.controller.js
+++ b/gui/app/scripts/controllers/report.controller.js
@@ -54,7 +54,7 @@ angular.module('yardStickGui2App')
}
$scope.goToExternal = function goToExternal(id) {
- var url = External_URL + ':' + $scope.jumpPort + '/dashboard/db' + '/' + id;
+ var url = Grafana_URL +':'+$scope.jumpPort+'/dashboard/db'+ '/' + id;
window.open(url, '_blank');
}
diff --git a/gui/app/views/environmentList.html b/gui/app/views/environmentList.html
index 29273a724..1b00b1cc6 100644
--- a/gui/app/views/environmentList.html
+++ b/gui/app/views/environmentList.html
@@ -22,21 +22,18 @@
<div dir-paginate="env in environmentList | orderBy:'-id' | itemsPerPage: 10 ">
<div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;">
- <div> <a style="color:#e95420" ng-click="gotoDetail('false',env.uuid)">{{env.name}}</a></div>
+ <div> <a style="color:#4dc5cf" ng-click="gotoDetail('false',env.uuid)">{{env.name}}</a></div>
<div>
<!-- <button class="btn btn-default btn-sm" ng-click="openDeleteEnv(env.uuid,'environment')">Delete</button> -->
<div class="btn-group" uib-dropdown is-open="status.isopen" style="margin-right:60px;">
<button id="single-button" type="button" class="btn btn-default btn-sm" uib-dropdown-toggle>
- Modify <span class="caret"></span>
+ delete <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
- <li role="menuitem"><a ng-click="openDeleteEnv(env.uuid,'environment')">Delete</a></li>
- <!-- <li role="menuitem"><a href="#">Another action</a></li>
- <li role="menuitem"><a href="#">Something else here</a></li>
- <li class="divider"></li>
- <li role="menuitem"><a href="#">Separated link</a></li> -->
+ <li role="menuitem"><a ng-click="openDeleteEnv(env.uuid,'environment')">delete</a></li>
+
</ul>
</div>
</div>
diff --git a/gui/app/views/layout/header.html b/gui/app/views/layout/header.html
index 033322a62..ad90de952 100644
--- a/gui/app/views/layout/header.html
+++ b/gui/app/views/layout/header.html
@@ -4,8 +4,9 @@
<div class="navbar-header">
-
+ <img src="images/logo.png" style="width:50px;height:50px;float:left;margin-left:20px;" />
<a class="navbar-brand" href="#/">Yardstick</a>
+
</div>
@@ -33,11 +34,11 @@
.navbar {
border-radius: 0px;
- background-color: #e95420;
+ background-color: #CAEEF1;
color: #fff;
}
.navbar-default .navbar-brand {
- color: #fff;
+ color: #333;
}
-</style>
+</style> \ No newline at end of file
diff --git a/gui/app/views/layout/sideNav.html b/gui/app/views/layout/sideNav.html
index 42dcbbc6e..4fc99cd4f 100644
--- a/gui/app/views/layout/sideNav.html
+++ b/gui/app/views/layout/sideNav.html
@@ -90,7 +90,7 @@
<style>
.bs-sidenav {
- margin-top: 40px;
+ margin-top: 21px;
margin-bottom: 20px;
width: 124px;
}
diff --git a/gui/app/views/layout/sideNav2.html b/gui/app/views/layout/sideNav2.html
index 104a9c6cf..93e0de4be 100644
--- a/gui/app/views/layout/sideNav2.html
+++ b/gui/app/views/layout/sideNav2.html
@@ -66,7 +66,7 @@
<style>
.bs-sidenav {
- margin-top: 40px;
+ margin-top: 21px;
margin-bottom: 20px;
width: 124px;
}
diff --git a/gui/app/views/main.html b/gui/app/views/main.html
index d5f7a3af3..36bcbbd3c 100644
--- a/gui/app/views/main.html
+++ b/gui/app/views/main.html
@@ -105,13 +105,13 @@
}
.progressDefine>li.is-complete {
- color: #e95420;
+ color: #4dc5cf;
}
.progressDefine>li.is-complete:before,
.progressDefine>li.is-complete:after {
color: #FFF;
- background: #e95420;
+ background: #4dc5cf;
}
.progressDefine>li.is-active {
diff --git a/gui/app/views/main2.html b/gui/app/views/main2.html
index 661d604c6..3f49e82e0 100644
--- a/gui/app/views/main2.html
+++ b/gui/app/views/main2.html
@@ -105,13 +105,13 @@
}
.progressDefine>li.is-complete {
- color: #e95420;
+ color: #4dc5cf;
}
.progressDefine>li.is-complete:before,
.progressDefine>li.is-complete:after {
color: #FFF;
- background: #e95420;
+ background: #4dc5cf;
}
.progressDefine>li.is-active {
diff --git a/gui/app/views/modal/environmentDialog.html b/gui/app/views/modal/environmentDialog.html
index a5b88d240..389de8340 100644
--- a/gui/app/views/modal/environmentDialog.html
+++ b/gui/app/views/modal/environmentDialog.html
@@ -104,7 +104,7 @@
Next
</button>
<button class="btn btn-default" ng-click="goToPodPrev()" style="margin-right:5px;float:right">
- Previous
+ Back
</button>
</h3>
@@ -165,7 +165,7 @@
<h3>{{name}} -- Pod File
<div style="float:right">
- <button class="btn btn-default" ng-click="skipPodPrev()">Previous</button>
+ <button class="btn btn-default" ng-click="skipPodPrev()">Back</button>
<button class="btn btn-default" ng-click="skipPod()" ng-show="podData==null">Skip</button>
<button class="btn btn-default" ng-click="skipPod()" ng-show="podData!=null">Next</button>
@@ -234,7 +234,7 @@
<h3>{{name}} -- Container
<div style="float:right">
- <button class="btn btn-default" ng-click="skipContainerPrev()">Previous</button>
+ <button class="btn btn-default" ng-click="skipContainerPrev()">Back</button>
<button class="btn btn-default" ng-click="skipContainer()" ng-show="ifskipOrClose!=1">
Skip
</button>
diff --git a/gui/app/views/projectList.html b/gui/app/views/projectList.html
index ea6e63d6b..6edc32fc1 100644
--- a/gui/app/views/projectList.html
+++ b/gui/app/views/projectList.html
@@ -11,21 +11,21 @@
<div dw-loading="key" dw-loading-options="{text:'loading'}">
<div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;background-color:#f9f9f9;">
<div style="font-weight:600">Name</div>
- <div style="font-weight:600;margin-right:4px;">Action</div>
+ <div style="font-weight:600;margin-right:20px;">Action</div>
</div>
<div dir-paginate="project in projectListData | orderBy:'-id' | itemsPerPage: 10 ">
<div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;">
<div>
- <a ng-click="gotoDetail(project.uuid)" style="color:#e95420"> {{project.name}}</a>
+ <a ng-click="gotoDetail(project.uuid)" style="color:#4dc5cf"> {{project.name}}</a>
</div>
<div>
<!-- <button class="btn btn-default btn-sm" ng-click="gotoDetail(project.uuid)">Detail</button> -->
<!--<button class="btn btn-default btn-sm" ng-click="openDeleteEnv(project.uuid,'project')">Delete</button>-->
- <div class="btn-group" uib-dropdown is-open="status.isopen" style="margin-right:20px;">
+ <div class="btn-group" uib-dropdown is-open="status.isopen" >
<button id="single-button" type="button" class="btn btn-default btn-sm" uib-dropdown-toggle>
- Modify <span class="caret"></span>
+ delete <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
<li role="menuitem" ng-show="task.status!=0"><a ng-click="openDeleteEnv(project.uuid,'project')">delete</a></li>
diff --git a/gui/app/views/projectdetail.html b/gui/app/views/projectdetail.html
index ff61c5fed..357a26add 100644
--- a/gui/app/views/projectdetail.html
+++ b/gui/app/views/projectdetail.html
@@ -24,8 +24,8 @@
</tr>
<tr dir-paginate="task in finalTaskListDisplay | orderBy:'-id' | itemsPerPage: 6 " pagination-id="table">
- <td width="10%"> <a ng-click="gotoDetail(task.uuid)" style="color:#e95420"> {{task.name}} </a></td>
- <td width="40%">
+ <td width="20%"> <a ng-click="gotoDetail(task.uuid)" style="color:#4dc5cf"> {{task.name}} </a></td>
+ <td width="70%">
<div class="progree-parent" ng-show="task.status!=2">
<div class="progree-child" ng-style="{'width':task.stausWidth}">
</div>
@@ -37,11 +37,11 @@
</td>
- <td width="50%">
+ <td width="10%">
- <div class="btn-group" uib-dropdown is-open="status.isopen" style="margin-right:20px;">
+ <div class="btn-group" uib-dropdown is-open="status.isopen">
<button id="single-button" type="button" class="btn btn-default btn-sm" uib-dropdown-toggle>
- Modify <span class="caret"></span>
+ modify <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
<li role="menuitem" ng-show="task.status!=0"><a ng-click="runAtaskForTable(task.uuid)">run</a></li>
diff --git a/gui/app/views/suite.html b/gui/app/views/suite.html
index 8e1348333..652cf1e0e 100644
--- a/gui/app/views/suite.html
+++ b/gui/app/views/suite.html
@@ -9,39 +9,44 @@
</button>
- <!--<div ng-show="displayOpenrcFile!=null || displayOpenrcFile!=undefined">
- {{displayOpenrcFile.name}} last modified: {{filelastModified}}
- </div>-->
+
<hr/>
- <!--<div ng-repeat="env in environmentList">
- {{env.name}}
- </div>-->
+
<div dw-loading="key" dw-loading-options="{text:'loading'}">
- <div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;background-color: #f9f9f9;" >
- <div style="font-weight:600">Name</div>
- <div style="font-weight:600;margin-right:4px;">Operate</div>
+ <div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;background-color: #f9f9f9;">
+ <div style="font-weight:600">Name</div>
+ <div style="font-weight:600;margin-right:20px;">Action</div>
- </div>
+ </div>
- <div dir-paginate="suite in testsuitlist | itemsPerPage: 10">
- <div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;">
- <div>
- <a style="color:#e95420" ng-click="gotoDetail(suite)"> {{suite}}
+ <div dir-paginate="suite in testsuitlist | itemsPerPage: 10">
+ <div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;">
+ <div>
+ <a style="color:#4dc5cf" ng-click="gotoDetail(suite)"> {{suite}}
</a>
</div>
- <div>
- <!-- <button class="btn btn-default btn-sm" ng-click="gotoDetail(suite)">Detail</button> -->
- <button class="btn btn-default btn-sm" ng-click="openDeleteEnv(suite,'test suite')">Delete</button>
+ <div>
+ <!-- <button class="btn btn-default btn-sm" ng-click="openDeleteEnv(suite,'test suite')">Delete</button> -->
+ <div class="btn-group" uib-dropdown is-open="status.isopen">
+ <button id="single-button" type="button" class="btn btn-default btn-sm" uib-dropdown-toggle>
+ delete <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
+ <li role="menuitem"><a ng-click="openDeleteEnv(suite,'test suite')">delete</a></li>
+
+ </ul>
+ </div>
+
+ </div>
+
</div>
</div>
-
- </div>
- <center>
- <dir-pagination-controls></dir-pagination-controls>
- </center>
+ <center>
+ <dir-pagination-controls></dir-pagination-controls>
+ </center>
</div>
@@ -146,4 +151,4 @@
background-color: #EEEEEE;
border-radius: 5px;
}
-</style>
+</style> \ No newline at end of file
diff --git a/gui/app/views/testcaselist.html b/gui/app/views/testcaselist.html
index 3e8cfccf9..62237faa8 100644
--- a/gui/app/views/testcaselist.html
+++ b/gui/app/views/testcaselist.html
@@ -20,7 +20,7 @@
<div dw-loading="key" dw-loading-options="{text:'loading'}">
<div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;background-color: #f9f9f9">
<div style="font-weight:600">Name</div>
- <div style="font-weight:600;margin-right:4px;">Operate</div>
+ <div style="font-weight:600;margin-right:20px;">Action</div>
</div>
@@ -28,14 +28,22 @@
<div style="display:flex;flex-direction:row;justify-content:space-between;padding:8px;border-top: 1px solid #e9ecec;">
<div>
- <a style="color:#e95420" ng-click="gotoDetail(test.Name)">
+ <a style="color:#4dc5cf" ng-click="gotoDetail(test.Name)">
{{test.Name}}
</a>
</div>
<div style="font-size:10px;">{{test.Description}}</div>
<div>
- <!-- <button class="btn btn-default btn-sm" ng-click="gotoDetail(test.Name)">Detail</button> -->
- <button class="btn btn-default btn-sm" ng-click="openDeleteEnv(test.Name,'test case')">Delete</button>
+ <!-- <button class="btn btn-default btn-sm" ng-click="openDeleteEnv(test.Name,'test case')">Delete</button> -->
+ <div class="btn-group" uib-dropdown is-open="status.isopen" >
+ <button id="single-button" type="button" class="btn btn-default btn-sm" uib-dropdown-toggle>
+ delete <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
+ <li role="menuitem"><a ng-click="openDeleteEnv(test.Name,'test case')">delete</a></li>
+
+ </ul>
+ </div>
</div>
</div>
diff --git a/gui/bower.json b/gui/bower.json
index 6da3bee3c..d1d934f64 100644
--- a/gui/bower.json
+++ b/gui/bower.json
@@ -21,6 +21,9 @@
"angular-bootstrap": "^2.5.0",
"angular-sanitize": "^1.6.5"
},
+ "resolutions": {
+ "angular": "~1.6.x"
+ },
"devDependencies": {
"angular-mocks": "^1.4.0"
},
diff --git a/install.sh b/install.sh
index e82ae0233..8a5050a61 100755
--- a/install.sh
+++ b/install.sh
@@ -89,6 +89,7 @@ pip install -e .
/bin/bash "${PWD}/docker/uwsgi.sh"
/bin/bash "${PWD}/docker/nginx.sh"
cd "${PWD}/gui" && /bin/bash gui.sh
+mkdir -p /etc/nginx/yardstick
mv dist /etc/nginx/yardstick/gui
service nginx restart
diff --git a/run_tests.sh b/run_tests.sh
index 2519d94f6..2cf54c708 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -13,6 +13,9 @@
getopts ":f" FILE_OPTION
+# don't write .pyc files this can cause odd unittest results
+export PYTHONDONTWRITEBYTECODE=1
+
run_flake8() {
echo "Running flake8 ... "
logfile=test_results.log
diff --git a/samples/container_ping_vm.yaml b/samples/container_ping_vm.yaml
new file mode 100644
index 000000000..4b7b64f68
--- /dev/null
+++ b/samples/container_ping_vm.yaml
@@ -0,0 +1,57 @@
+##############################################################################
+# Copyright (c) 2017 Huawei 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
+##############################################################################
+
+---
+# Sample benchmark task config file
+# measure network latency using ping in container
+
+schema: "yardstick:task:0.1"
+
+scenarios:
+-
+ type: Ping
+ options:
+ packetsize: 200
+
+ host: host-k8s
+ target: target.openstack
+
+ runner:
+ type: Duration
+ duration: 60
+ interval: 1
+
+ sla:
+ max_rtt: 10
+ action: monitor
+
+contexts:
+-
+ type: Kubernetes
+ name: k8s
+
+ servers:
+ host:
+ image: openretriever/yardstick
+ command: /bin/bash
+ args: ['-c', 'chmod 700 ~/.ssh; chmod 600 ~/.ssh/*; service ssh restart;while true ; do sleep 10000; done']
+-
+ type: Heat
+ name: openstack
+ image: cirros-0.3.5
+ flavor: yardstick-flavor
+ user: cirros
+
+ servers:
+ target:
+ floating_ip: true
+
+ networks:
+ test:
+ cidr: '10.0.1.0/24'
diff --git a/samples/migrate-node-context.yaml b/samples/migrate-node-context.yaml
new file mode 100644
index 000000000..9fe1acf78
--- /dev/null
+++ b/samples/migrate-node-context.yaml
@@ -0,0 +1,40 @@
+---
+
+schema: "yardstick:task:0.1"
+
+scenarios:
+-
+ type: QemuMigrate
+ options:
+ smp: 2
+ migrate_to_port: 4444
+ incoming_ip: 0
+ qmp_src_path: "/tmp/qmp-sock-src"
+ qmp_dst_path: "/tmp/qmp-sock-dst"
+ max_down_time: "0.10"
+ host: kvm.LF
+ runner:
+ type: Duration
+ duration: 1
+ interval: 1
+ sla:
+ max_totaltime: 10
+ max_downtime: 0.10
+ max_setuptime: 0.50
+ action: monitor
+ setup_options:
+ rpm_dir: "/opt/rpm"
+ script_dir: "/opt/scripts"
+ image_dir: "/opt/image"
+ host_setup_seqs:
+ - "host-setup0.sh"
+ - "reboot"
+ - "host-setup1.sh"
+ - "setup-ovsdpdk.sh"
+ - "host-install-qemu.sh"
+ - "host-run-qemu4lm.sh"
+
+context:
+ type: Node
+ name: LF
+ file: /root/yardstick/pod.yaml
diff --git a/tests/ci/cover.sh b/tests/ci/cover.sh
index 71833757a..822ed2ff2 100644
--- a/tests/ci/cover.sh
+++ b/tests/ci/cover.sh
@@ -34,7 +34,10 @@ run_coverage_test() {
git checkout HEAD^
baseline_report=$(mktemp -t yardstick_coverageXXXXXXX)
- find . -type f -name "*.pyc" -delete && python setup.py testr --coverage --testr-args="$*"
+ # workaround 'db type could not be determined' bug
+ # https://bugs.launchpad.net/testrepository/+bug/1229445
+ rm -rf .testrepository
+ find . -type f -name "*.pyc" -delete && python setup.py testr --coverage --slowest --testr-args="$*"
coverage report > $baseline_report
baseline_missing=$(awk 'END { print $3 }' $baseline_report)
@@ -44,7 +47,10 @@ run_coverage_test() {
# Generate and save coverage report
current_report=$(mktemp -t yardstick_coverageXXXXXXX)
- find . -type f -name "*.pyc" -delete && python setup.py testr --coverage --testr-args="$*"
+ # workaround 'db type could not be determined' bug
+ # https://bugs.launchpad.net/testrepository/+bug/1229445
+ rm -rf .testrepository
+ find . -type f -name "*.pyc" -delete && python setup.py testr --coverage --slowest --testr-args="$*"
coverage report > $current_report
current_missing=$(awk 'END { print $3 }' $current_report)
diff --git a/tests/opnfv/test_suites/opnfv_os-odl-sfc-ha_daily.yaml b/tests/opnfv/test_suites/opnfv_os-odl-sfc-ha_daily.yaml
new file mode 100644
index 000000000..b464bfeae
--- /dev/null
+++ b/tests/opnfv/test_suites/opnfv_os-odl-sfc-ha_daily.yaml
@@ -0,0 +1,62 @@
+##############################################################################
+# 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
+##############################################################################
+---
+# os-odl-sfc-ha daily task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "os-odl-sfc-ha"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc002.yaml
+-
+ file_name: opnfv_yardstick_tc005.yaml
+-
+ file_name: opnfv_yardstick_tc010.yaml
+-
+ file_name: opnfv_yardstick_tc011.yaml
+-
+ file_name: opnfv_yardstick_tc012.yaml
+-
+ file_name: opnfv_yardstick_tc014.yaml
+-
+ file_name: opnfv_yardstick_tc037.yaml
+-
+ file_name: opnfv_yardstick_tc055.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"file": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml",
+ "host": "node5.yardstick-TC055"}'
+-
+ file_name: opnfv_yardstick_tc063.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"file": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml",
+ "host": "node5.yardstick-TC063"}'
+-
+ file_name: opnfv_yardstick_tc069.yaml
+-
+ file_name: opnfv_yardstick_tc070.yaml
+-
+ file_name: opnfv_yardstick_tc071.yaml
+-
+ file_name: opnfv_yardstick_tc072.yaml
+-
+ file_name: opnfv_yardstick_tc075.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"file": "etc/yardstick/nodes/compass_sclab_physical/pod.yaml",
+ "host": "node1.LF"}'
diff --git a/tests/unit/benchmark/scenarios/compute/test_qemumigrate.py b/tests/unit/benchmark/scenarios/compute/test_qemumigrate.py
new file mode 100644
index 000000000..9514729ba
--- /dev/null
+++ b/tests/unit/benchmark/scenarios/compute/test_qemumigrate.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+
+##############################################################################
+# Copyright (c) 2015 Huawei Technologies Co.,Ltd and other.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+# Unittest for yardstick.benchmark.scenarios.compute.qemu_migrate.QemuMigrate
+
+from __future__ import absolute_import
+
+import unittest
+
+import mock
+from oslo_serialization import jsonutils
+
+from yardstick.benchmark.scenarios.compute import qemu_migrate
+
+
+@mock.patch('yardstick.benchmark.scenarios.compute.qemu_migrate.ssh')
+class QemuMigrateTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.scenario_cfg = {
+ "host": "kvm.LF",
+ "setup_options": {
+ "rpm_dir": "/opt/rpm",
+ "script_dir": "/opt/scripts",
+ "image_dir": "/opt/image",
+ "host_setup_seqs": [
+ "host-setup0.sh",
+ "host-setup1.sh",
+ "setup-ovsdpdk.sh",
+ "host-install-qemu.sh",
+ "host-run-qemu4lm.sh"
+ ]
+ },
+ "sla": {
+ "action": "monitor",
+ "max_totaltime": 10,
+ "max_downtime": 0.10,
+ "max_setuptime": 0.50
+ },
+ "options": {
+ "smp": 99,
+ "migrate_to_port": 4444,
+ "incoming_ip": 0,
+ "qmp_src_path": "/tmp/qmp-sock-src",
+ "qmp_dst_path": "/tmp/qmp-sock-dst",
+ "max_down_time": "0.10"
+ }
+ }
+ self.context_cfg = {
+ "host": {
+ "ip": "10.229.43.154",
+ "key_filename": "/yardstick/resources/files/yardstick_key",
+ "role": "BareMetal",
+ "name": "kvm.LF",
+ "user": "root"
+ }
+ }
+
+ def test_qemu_migrate_successful_setup(self, mock_ssh):
+
+ q = qemu_migrate.QemuMigrate(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+
+ q.setup()
+ self.assertIsNotNone(q.host)
+ self.assertEqual(q.setup_done, True)
+
+ def test_qemu_migrate_successful_no_sla(self, mock_ssh):
+ result = {}
+ self.scenario_cfg.pop("sla", None)
+ q = qemu_migrate.QemuMigrate(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+ q.setup()
+
+ sample_output = '{"totaltime": 15, "downtime": 2, "setuptime": 1}'
+ mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '')
+
+ q.run(result)
+ expected_result = jsonutils.loads(sample_output)
+ self.assertEqual(result, expected_result)
+
+ def test_qemu_migrate_successful_sla(self, mock_ssh):
+ result = {}
+ self.scenario_cfg.update({"sla": {
+ "action": "monitor",
+ "max_totaltime": 15,
+ "max_downtime": 2,
+ "max_setuptime": 1
+ }
+ })
+ q = qemu_migrate.QemuMigrate(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+ q.setup()
+
+ sample_output = '{"totaltime": 15, "downtime": 2, "setuptime": 1}'
+ mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '')
+
+ q.run(result)
+ expected_result = jsonutils.loads(sample_output)
+ self.assertEqual(result, expected_result)
+
+ def test_qemu_migrate_unsuccessful_sla_totaltime(self, mock_ssh):
+
+ result = {}
+ self.scenario_cfg.update({"sla": {"max_totaltime": 10}})
+ q = qemu_migrate.QemuMigrate(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+ q.setup()
+
+ sample_output = '{"totaltime": 15, "downtime": 2, "setuptime": 1}'
+
+ mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '')
+ self.assertRaises(AssertionError, q.run, result)
+
+ def test_qemu_migrate_unsuccessful_sla_downtime(self, mock_ssh):
+
+ result = {}
+ self.scenario_cfg.update({"sla": {"max_downtime": 0.10}})
+ q = qemu_migrate.QemuMigrate(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+ q.setup()
+
+ sample_output = '{"totaltime": 15, "downtime": 2, "setuptime": 1}'
+
+ mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '')
+ self.assertRaises(AssertionError, q.run, result)
+
+ def test_qemu_migrate_unsuccessful_sla_setuptime(self, mock_ssh):
+
+ result = {}
+ self.scenario_cfg.update({"sla": {"max_setuptime": 0.50}})
+ q = qemu_migrate.QemuMigrate(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+ q.setup()
+
+ sample_output = '{"totaltime": 15, "downtime": 2, "setuptime": 1}'
+
+ mock_ssh.SSH.from_node().execute.return_value = (0, sample_output, '')
+ self.assertRaises(AssertionError, q.run, result)
+
+ def test_qemu_migrate_unsuccessful_script_error(self, mock_ssh):
+
+ result = {}
+ self.scenario_cfg.update({"sla": {"max_totaltime": 10}})
+ q = qemu_migrate.QemuMigrate(self.scenario_cfg, self.context_cfg)
+ mock_ssh.SSH.from_node().execute.return_value = (0, '', '')
+ q.setup()
+
+
+ mock_ssh.SSH.from_node().execute.return_value = (1, '', 'FOOBAR')
+ self.assertRaises(RuntimeError, q.run, result)
+
+
+def main():
+ unittest.main()
+
+if __name__ == '__main__':
+ main()
diff --git a/yardstick/benchmark/scenarios/compute/qemu_migrate.py b/yardstick/benchmark/scenarios/compute/qemu_migrate.py
new file mode 100644
index 000000000..cee87a545
--- /dev/null
+++ b/yardstick/benchmark/scenarios/compute/qemu_migrate.py
@@ -0,0 +1,155 @@
+from __future__ import absolute_import
+from __future__ import print_function
+
+import logging
+import os
+import re
+import time
+
+
+import pkg_resources
+from oslo_serialization import jsonutils
+
+import yardstick.ssh as ssh
+from yardstick.benchmark.scenarios import base
+
+LOG = logging.getLogger(__name__)
+LOG.setLevel(logging.DEBUG)
+
+
+class QemuMigrate(base.Scenario):
+ """
+ Execute a live migration for two host using qemu
+
+ """
+
+ __scenario_type__ = "QemuMigrate"
+
+ TARGET_SCRIPT = "qemu_migrate_benchmark.bash"
+ WORKSPACE = "/root/workspace"
+ REBOOT_CMD_PATTERN = r";\s*reboot\b"
+
+ def __init__(self, scenario_cfg, context_cfg):
+ self.scenario_cfg = scenario_cfg
+ self.context_cfg = context_cfg
+ self.setup_done = False
+
+ def _connect_host(self):
+ host = self.context_cfg["host"]
+ self.host = ssh.SSH.from_node(host, defaults={"user": "root"})
+ self.host.wait(timeout=600)
+
+ def _put_files(self, client):
+ setup_options = self.scenario_cfg["setup_options"]
+ script_dir = setup_options["script_dir"]
+ LOG.debug("Send scripts from %s to workspace %s",
+ script_dir, self.WORKSPACE)
+ client.put(script_dir, self.WORKSPACE, recursive=True)
+
+ def _run_setup_cmd(self, client, cmd):
+ LOG.debug("Run cmd: %s", cmd)
+ status, stdout, stderr = client.execute(cmd)
+ if status:
+ if re.search(self.REBOOT_CMD_PATTERN, cmd):
+ LOG.debug("Error on reboot")
+ else:
+ raise RuntimeError(stderr)
+
+ def _run_host_setup_scripts(self, scripts):
+ setup_options = self.scenario_cfg["setup_options"]
+ script_dir = os.path.basename(setup_options["script_dir"])
+
+ for script in scripts:
+ cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
+ (self.WORKSPACE, script_dir, script)
+ self._run_setup_cmd(self.host, cmd)
+
+ if re.search(self.REBOOT_CMD_PATTERN, cmd):
+ time.sleep(3)
+ self._connect_host()
+
+ def setup(self):
+ """scenario setup"""
+ setup_options = self.scenario_cfg["setup_options"]
+ host_setup_seqs = setup_options["host_setup_seqs"]
+
+ self._connect_host()
+ self._put_files(self.host)
+ self._run_host_setup_scripts(host_setup_seqs)
+
+ # copy script to host
+ self.target_script = pkg_resources.resource_filename(
+ "yardstick.benchmark.scenarios.compute",
+ QemuMigrate.TARGET_SCRIPT)
+ self.host.put_file(self.target_script, "~/qemu_migrate_benchmark.sh")
+
+ self.setup_done = True
+
+ def run(self, result):
+ """execute the benchmark"""
+
+ options = self.scenario_cfg["options"]
+ smp = options.get("smp", 2)
+ qmp_sock_src = options.get("qmp_src_path", "/tmp/qmp-sock-src")
+ qmp_sock_dst = options.get("qmp_dst_path", "/tmp/qmp-sock-dst")
+ incoming_ip = options.get("incoming_ip", 0)
+ migrate_to_port = options.get("migrate_to_port", 4444)
+ max_down_time = options.get("max_down_time", 0.10)
+ cmd_args = " %s %s %s %s %s %s" %\
+ (smp, qmp_sock_src, qmp_sock_dst, incoming_ip,
+ migrate_to_port, max_down_time)
+ cmd = "bash migrate_benchmark.sh %s" % (cmd_args)
+ LOG.debug("Executing command: %s", cmd)
+ status, stdout, stderr = self.host.execute(cmd)
+ if status:
+ raise RuntimeError(stderr)
+
+ result.update(jsonutils.loads(stdout))
+
+ if "sla" in self.scenario_cfg:
+ sla_error = ""
+ for t, timevalue in result.items():
+ if 'max_%s' % t not in self.scenario_cfg['sla']:
+ continue
+
+ sla_time = int(self.scenario_cfg['sla'][
+ 'max_%s' % t])
+ timevalue = int(timevalue)
+ if timevalue > sla_time:
+ sla_error += "%s timevalue %d > sla:max_%s(%d); " % \
+ (t, timevalue, t, sla_time)
+ assert sla_error == "", sla_error
+
+
+def _test(): # pragma: no cover
+ """internal test function"""
+ key_filename = pkg_resources.resource_filename("yardstick.resources",
+ "files/yardstick_key")
+ ctx = {
+ "host": {
+ "ip": "10.229.47.137",
+ "user": "root",
+ "key_filename": key_filename
+ }
+ }
+
+ logger = logging.getLogger("yardstick")
+ logger.setLevel(logging.DEBUG)
+ options = {
+ "smp": 2,
+ "migrate_to_port": 4444,
+ "incoming_ip": 0,
+ "qmp_sock_src": "/tmp/qmp-sock-src",
+ "qmp_sock_dst": "/tmp/qmp-sock-dst",
+ "max_down_time": 0.10
+ }
+ args = {
+ "options": options
+ }
+ result = {}
+ migrate = QemuMigrate(args, ctx)
+ migrate.run(result)
+ print(result)
+
+if __name__ == '__main__': # pragma: no cover
+ _test()
diff --git a/yardstick/benchmark/scenarios/compute/qemu_migrate_benchmark.bash b/yardstick/benchmark/scenarios/compute/qemu_migrate_benchmark.bash
new file mode 100644
index 000000000..552098103
--- /dev/null
+++ b/yardstick/benchmark/scenarios/compute/qemu_migrate_benchmark.bash
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+#############################################################################
+#Copyright (c) 2015 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
+##############################################################################
+
+set -e
+
+# Commandline arguments
+
+src=$2
+dst_ip=$4
+migrate_to_port=$5
+max_down_time=$6
+
+OUTPUT_FILE=/tmp/output-qemu.log
+
+do_migrate()
+{
+# local src=`echo $OPTIONS | cut -d ':' -f 2 | cut -d ',' -f 1`
+ echo "info status" | nc -U $src
+ # with no speed limit
+ echo "migrate_set_speed 0" |nc -U $src
+ # set the expected max downtime
+ echo "migrate_set_downtime ${max_down_time}" |nc -U $src
+ # start live migration
+ echo "migrate -d tcp:${dst_ip}:$migrate_to_port" |nc -U $src
+ # wait until live migration completed
+ status=""
+ while [ "${status}" == "" ]
+ do
+ status=`echo "info migrate" | nc -U $src |grep completed | cut -d: -f2`
+ echo ${status}
+ sleep 1;
+ done
+} >/dev/null
+
+output_qemu()
+{
+ # print detail information
+ echo "info migrate" | nc -U $src
+ echo "quit" | nc -U $src
+ sleep 5
+
+} > $OUTPUT_FILE
+
+output_json()
+{
+totaltime=$(grep "total time" $OUTPUT_FILE | cut -d' ' -f3)
+downtime=$(grep "downtime" $OUTPUT_FILE | cut -d' ' -f2)
+setuptime=$(grep "setup" $OUTPUT_FILE | cut -d' ' -f2)
+echo -e "{ \
+ \"totaltime\":\"$totaltime\", \
+ \"downtime\":\"$downtime\", \
+ \"setuptime\":\"$setuptime\" \
+ }"
+}
+# main entry
+main()
+{
+ do_migrate
+}
+main
diff --git a/yardstick/cmd/NSBperf.py b/yardstick/cmd/NSBperf.py
index 4e7590ea5..2dc0f65e7 100755
--- a/yardstick/cmd/NSBperf.py
+++ b/yardstick/cmd/NSBperf.py
@@ -30,13 +30,6 @@ from six.moves import input
CLI_PATH = os.path.dirname(os.path.realpath(__file__))
REPO_PATH = os.path.abspath(os.path.join(CLI_PATH, os.pardir))
-PYTHONPATH = os.environ.get("PYTHONPATH", False)
-VIRTUAL_ENV = os.environ.get("VIRTUAL_ENV", False)
-
-
-if not PYTHONPATH or not VIRTUAL_ENV:
- print("Please setup env PYTHONPATH & VIRTUAL_ENV environment varaible.")
- raise SystemExit(1)
def sigint_handler(*args, **kwargs):
diff --git a/yardstick/cmd/commands/task.py b/yardstick/cmd/commands/task.py
index 03f6b1b1e..8d8ea2b3c 100644
--- a/yardstick/cmd/commands/task.py
+++ b/yardstick/cmd/commands/task.py
@@ -51,11 +51,17 @@ class TaskCommands(object): # pragma: no cover
self.output_file = param.output_file
try:
- Task().start(param, **kwargs)
+ result = Task().start(param, **kwargs)
except Exception as e:
self._write_error_data(e)
LOG.exception("")
+ if result.get('result', {}).get('criteria') == 'PASS':
+ LOG.info('Task Success')
+ else:
+ LOG.info('Task Failed')
+ raise RuntimeError('Task Failed')
+
def _write_error_data(self, error):
data = {'status': 2, 'result': str(error)}
write_json_to_file(self.output_file, data)