aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/images/Ims_overview.pngbin0 -> 11947 bytes
-rw-r--r--docs/images/overall_description.pngbin0 -> 105870 bytes
-rw-r--r--docs/images/vPing.pngbin0 -> 30609 bytes
-rw-r--r--testcases/VIM/OpenStack/CI/libraries/run_rally.py150
-rw-r--r--testcases/VIM/OpenStack/CI/suites/opnfv-requests.json16
-rw-r--r--testcases/vPing/CI/libraries/vPing.py169
6 files changed, 282 insertions, 53 deletions
diff --git a/docs/images/Ims_overview.png b/docs/images/Ims_overview.png
new file mode 100644
index 00000000..4b447d40
--- /dev/null
+++ b/docs/images/Ims_overview.png
Binary files differ
diff --git a/docs/images/overall_description.png b/docs/images/overall_description.png
new file mode 100644
index 00000000..45aadf1b
--- /dev/null
+++ b/docs/images/overall_description.png
Binary files differ
diff --git a/docs/images/vPing.png b/docs/images/vPing.png
new file mode 100644
index 00000000..fa223d13
--- /dev/null
+++ b/docs/images/vPing.png
Binary files differ
diff --git a/testcases/VIM/OpenStack/CI/libraries/run_rally.py b/testcases/VIM/OpenStack/CI/libraries/run_rally.py
index da5e6adc..898fca6b 100644
--- a/testcases/VIM/OpenStack/CI/libraries/run_rally.py
+++ b/testcases/VIM/OpenStack/CI/libraries/run_rally.py
@@ -8,8 +8,35 @@
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
-import re, json, os, sys, urllib2
-
+import re, json, os, urllib2, argparse, logging
+
+""" tests configuration """
+tests = ['authenticate', 'glance', 'heat', 'keystone', 'neutron', 'nova', 'tempest', 'vm', 'all']
+parser = argparse.ArgumentParser()
+parser.add_argument("test_name", help="The name of the test you want to perform with rally. "
+ "Possible values are : "
+ "[ {d[0]} | {d[1]} | {d[2]} | {d[3]} | {d[4]} | {d[5]} | {d[6]} "
+ "| {d[7]} | {d[8]} ]. The 'all' value performs all the tests scenarios "
+ "except 'tempest'".format(d=tests))
+
+parser.add_argument("-d", "--debug", help="Debug mode", action="store_true")
+args = parser.parse_args()
+
+""" logging configuration """
+logger = logging.getLogger('run_rally')
+logger.setLevel(logging.DEBUG)
+
+ch = logging.StreamHandler()
+if args.debug:
+ ch.setLevel(logging.DEBUG)
+else:
+ ch.setLevel(logging.INFO)
+
+formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ch.setFormatter(formatter)
+logger.addHandler(ch)
+
+
def get_task_id(cmd_raw):
"""
get task id from command rally result
@@ -23,7 +50,8 @@ def get_task_id(cmd_raw):
if match:
return match.group(1)
return None
-
+
+
def task_succeed(json_raw):
"""
Parse JSON from rally JSON results
@@ -43,94 +71,110 @@ def task_succeed(json_raw):
return True
+
def run_task(test_name):
"""
the "main" function of the script who lunch rally for a task
:param test_name: name for the rally test
:return: void
"""
+ logger.info('starting {} test ...'.format(test_name))
""" get the date """
cmd = os.popen("date '+%d%m%Y_%H%M'")
test_date = cmd.read().rstrip()
- """ check directory for test scenarios files or retrieve from git otherwise"""
+ """ check directory for scenarios test files or retrieve from git otherwise"""
+ proceed_test = True
tests_path = "./scenarios"
test_file_name = '{}/opnfv-{}.json'.format(tests_path, test_name)
if not os.path.exists(test_file_name):
- retrieve_test_cases_file(test_name, tests_path)
- print "Scenario successfully downloaded"
-
- print "Start test..."
- cmd = os.popen("rally task start --abort-on-sla-failure %s" % test_file_name)
- task_id = get_task_id(cmd.read())
-
- if task_id is None:
- print "./run_rally : failed to retrieve task_id"
- exit(-1)
-
- """ check for result directory and create it otherwise """
- report_path = "./results"
- if not os.path.exists(report_path):
- os.makedirs(report_path)
-
- report_file_name = '{}/opnfv-{}-{}.html'.format(report_path, test_name, test_date)
-
- os.popen("rally task report %s --out %s" % (task_id, report_file_name))
- cmd = os.popen("rally task results %s" % task_id)
- if task_succeed(cmd.read()):
- print "OK"
+ logger.debug('{} does not exists'.format(test_file_name))
+ proceed_test = retrieve_test_cases_file(test_name, tests_path)
+ logger.debug('successfully downloaded to : {}'.format(test_file_name))
+
+ """ we do the test only if we have a scenario test file """
+ if proceed_test:
+ cmd_line = "rally task start --abort-on-sla-failure %s" % test_file_name
+ logger.debug('running command line : {}'.format(cmd_line))
+ cmd = os.popen(cmd_line)
+ task_id = get_task_id(cmd.read())
+ logger.debug('task_id : {}'.format(task_id))
+
+ if task_id is None:
+ logger.error("failed to retrieve task_id")
+ exit(-1)
+
+ """ check for result directory and create it otherwise """
+ report_path = "./results"
+ if not os.path.exists(report_path):
+ logger.debug('does not exists, we create it'.format(report_path))
+ os.makedirs(report_path)
+
+ """ write html report file """
+ report_file_name = '{}/opnfv-{}-{}.html'.format(report_path, test_name, test_date)
+ cmd_line = "rally task report %s --out %s" % (task_id, report_file_name)
+ logger.debug('running command line : {}'.format(cmd_line))
+ os.popen(cmd_line)
+
+ """ get and save rally operation JSON result """
+ cmd_line = "rally task results %s" % task_id
+ logger.debug('running command line : {}'.format(cmd_line))
+ cmd = os.popen(cmd_line)
+ json_results = cmd.read()
+ with open('{}/opnfv-{}-{}.json'.format(report_path, test_name, test_date), 'w') as f:
+ logger.debug('saving json file')
+ f.write(json_results)
+
+ """ parse JSON operation result """
+ if task_succeed(json_results):
+ print '{} OK'.format(test_date)
+ else:
+ print '{} KO'.format(test_date)
else:
- print "KO"
+ logger.error('{} test failed, unable to find a scenario test file'.format(test_name))
def retrieve_test_cases_file(test_name, tests_path):
"""
Retrieve from github the sample test files
- :return: void
+ :return: Boolean that indicates the retrieval status
"""
""" do not add the "/" at the end """
url_base = "https://git.opnfv.org/cgit/functest/plain/testcases/VIM/OpenStack/CI/suites"
test_file_name = 'opnfv-{}.json'.format(test_name)
- print 'fetching {}/{} ...'.format(url_base, test_file_name)
- response = urllib2.urlopen('{}/{}'.format(url_base, test_file_name))
+ logger.info('fetching {}/{} ...'.format(url_base, test_file_name))
+
+ try:
+ response = urllib2.urlopen('{}/{}'.format(url_base, test_file_name))
+ except (urllib2.HTTPError, urllib2.URLError):
+ return False
file_raw = response.read()
- """ check if the test path existe otherwise we create it """
+ """ check if the test path exist otherwise we create it """
if not os.path.exists(tests_path):
os.makedirs(tests_path)
- with open('{}/{}'.format(tests_path,test_file_name), 'w') as file:
- file.write(file_raw)
-
-
+ with open('{}/{}'.format(tests_path, test_file_name), 'w') as f:
+ f.write(file_raw)
+ return True
+
+
def main():
""" configure script """
- tests = ['authenticate','glance','heat','keystone','neutron','nova','tempest','vm', 'all'];
-
-
- if len(sys.argv) != 2:
- options = '{d[0]} | {d[1]} | {d[2]} | {d[3]} | {d[4]} | {d[5]} | {d[6]} | {d[7]} | {d[8]}'.format(d=tests)
- print "./run_rally [", options, "]"
+ if not (args.test_name in tests):
+ logger.error('argument not valid')
exit(-1)
- test_name = sys.argv[1]
-
- if not (test_name in tests):
- print "argument not valid"
- exit(-1)
-
- if test_name == "all":
+
+ if args.test_name == "all":
for test_name in tests:
if not (test_name == 'all' or test_name == 'tempest'):
print(test_name)
run_task(test_name)
-
else:
- run_task(test_name)
-
-
+ run_task(args.test_name)
+
if __name__ == '__main__':
main()
-
diff --git a/testcases/VIM/OpenStack/CI/suites/opnfv-requests.json b/testcases/VIM/OpenStack/CI/suites/opnfv-requests.json
new file mode 100644
index 00000000..9936e2fd
--- /dev/null
+++ b/testcases/VIM/OpenStack/CI/suites/opnfv-requests.json
@@ -0,0 +1,16 @@
+{
+ "Requests.check_response": [
+ {
+ "args": {
+ "url": "http://www.google.com",
+ "response": 302
+ },
+ "runner": {
+ "type": "constant",
+ "times": 20,
+ "concurrency": 5
+ }
+ }
+ ]
+}
+
diff --git a/testcases/vPing/CI/libraries/vPing.py b/testcases/vPing/CI/libraries/vPing.py
new file mode 100644
index 00000000..b304f721
--- /dev/null
+++ b/testcases/vPing/CI/libraries/vPing.py
@@ -0,0 +1,169 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2015 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
+#
+# This script boots the VM1 and allocates IP address from Nova
+# Later, the VM2 boots then execute cloud-init to ping VM1.
+# After successful ping, both the VMs are deleted.
+#
+# Note: this is script works only with Ubuntu image, not with Cirros image
+#
+
+import os
+import pprint
+import subprocess
+import time
+import novaclient.v1_1.client as novaclient
+import cinderclient.v1.client as cinderclient
+pp = pprint.PrettyPrinter(indent=4)
+
+def pMsg(value):
+ """pretty printing"""
+ pp.pprint(value)
+
+def print_title(title):
+ """Print titles"""
+ print "\n"+"#"*40+"\n# "+title+"\n"+"#"*40+"\n"
+
+def get_credentials(service):
+ """Returns a creds dictionary filled with the following keys:
+ * username
+ * password/api_key (depending on the service)
+ * tenant_name/project_id (depending on the service)
+ * auth_url
+ :param service: a string indicating the name of the service
+ requesting the credentials.
+ """
+ creds = {}
+ # Unfortunately, each of the OpenStack client will request slightly
+ # different entries in their credentials dict.
+ if service.lower() in ("nova", "cinder"):
+ password = "api_key"
+ tenant = "project_id"
+ else:
+ password = "password"
+ tenant = "tenant_name"
+
+ # The most common way to pass these info to the script is to do it through
+ # environment variables.
+ creds.update({
+ "username": os.environ.get('OS_USERNAME', "admin"), # add your cloud username details
+ password: os.environ.get("OS_PASSWORD", "test"), # add password
+ "auth_url": os.environ.get("OS_AUTH_URL","http://192.168.20.71:5000/v2.0"), # Auth URL
+ tenant: os.environ.get("OS_TENANT_NAME", "invisible_to_admin"),
+ })
+
+ return creds
+
+
+def get_server(creds, servername):
+ nova = novaclient.Client(**creds)
+ return nova.servers.find(name=servername)
+
+
+def waitVmActive(nova,vm):
+ # sleep and wait for VM status change
+ pMsg(vm.status)
+ while vm.status == "BUILD":
+ time.sleep(1)
+ vm = nova.servers.get(vm.id)
+ pMsg(vm.status)
+
+def main():
+ creds = get_credentials("nova")
+ nova = novaclient.Client(**creds)
+ cinder = cinderclient.Client(**creds)
+
+ #print images and server resources
+ print_title("images list")
+ pMsg(nova.images.list())
+
+ print_title("servers list")
+ pMsg(nova.servers.list())
+
+
+ # boot VM 1
+ # basic boot
+ # tune (e.g. flavor, images, network) to your specific openstack configuration here
+ f = nova.flavors.find(name = 'm1.small')
+ i = nova.images.find(name = 'Ubuntu 14.04 (amd64)')
+ n = nova.networks.find(label = 'private')
+ u = "#cloud-config\npassword: opnfv\nchpasswd: { expire: False }\nssh_pwauth: True"
+ #k = "demo-key"
+
+ # create VM
+ vm1 = nova.servers.create(
+ name = "opnfv-vping-1",
+ flavor = f,
+ image = i,
+ nics = [{"net-id": n.id}],
+ #key_name = k,
+ userdata = u,
+ )
+
+ pMsg(vm1)
+
+
+ #wait until VM status is active
+ waitVmActive(nova,vm1)
+
+ #retrieve IP of first VM
+ server = get_server(creds, "opnfv-vping-1")
+ pMsg(server.networks)
+ # theoretically there is only one IP address so we take the first element of the table
+ test_ip = server.networks.get('private')[0]
+ test_cmd = '/tmp/vping.sh %s'%test_ip
+
+
+ # boot VM 2
+ # we will boot then execute a ping script with cloud-init
+ # the long chain corresponds to the ping procedure converted with base 64
+ # tune (e.g. flavor, images, network) to your specific openstack configuration here
+ f = nova.flavors.find(name = 'm1.small')
+ i = nova.images.find(name = 'Ubuntu 14.04 (amd64)')
+ n = nova.networks.find(label = 'private')
+ # use base 64 format becaus bad surprises with sh script with cloud-init but script is just pinging
+ u = "#cloud-config\npassword: opnfv\nchpasswd: { expire: False }\nssh_pwauth: True\nwrite_files:\n- encoding: b64\n path: /tmp/vping.sh\n permissions: '0777'\n owner: root:root\n content: IyEvYmluL2Jhc2gKCgoKcGluZyAtYyAxICQxIDI+JjEgPi9kZXYvbnVsbApSRVM9JD8KaWYgWyAiWiRSRVMiID0gIlowIiBdIDsgdGhlbgogIGVjaG8gInZQaW5nIE9LIgplbHNlCiAgZWNobyAidlBpbmcgS08iCmZpCg==\nruncmd:\n - [ sh, -c, %s]"%test_cmd
+ #k = "demo-key"
+
+ # create VM
+ vm2 = nova.servers.create(
+ name = "opnfv-vping-2",
+ flavor = f,
+ image = i,
+ nics = [{"net-id": n.id}],
+ #key_name = k,
+ userdata = u,
+ #security_groups = s,
+ #config_drive = v.id
+ )
+
+ pMsg(vm2)
+
+ waitVmActive(nova,vm2)
+
+ console_log = vm2.get_console_output()
+
+
+ while not ("vPing" in console_log):
+ time.sleep(1)
+ console_log = vm2.get_console_output()
+
+ # report if the test is failed
+ if "vPing" in console_log:
+ pMsg("vPing is OK")
+ else:
+ pMsg("no vPing detected....")
+
+ # delete both VMs
+ nova.servers.delete(vm1)
+ nova.servers.delete(vm2)
+ pMsg ("VM instances have been terminated!")
+
+
+if __name__ == '__main__':
+ main()