diff options
-rw-r--r-- | docs/images/Ims_overview.png | bin | 0 -> 11947 bytes | |||
-rw-r--r-- | docs/images/overall_description.png | bin | 0 -> 105870 bytes | |||
-rw-r--r-- | docs/images/vPing.png | bin | 0 -> 30609 bytes | |||
-rw-r--r-- | testcases/VIM/OpenStack/CI/libraries/run_rally.py | 150 | ||||
-rw-r--r-- | testcases/VIM/OpenStack/CI/suites/opnfv-requests.json | 16 | ||||
-rw-r--r-- | testcases/vPing/CI/libraries/vPing.py | 169 |
6 files changed, 282 insertions, 53 deletions
diff --git a/docs/images/Ims_overview.png b/docs/images/Ims_overview.png Binary files differnew file mode 100644 index 00000000..4b447d40 --- /dev/null +++ b/docs/images/Ims_overview.png diff --git a/docs/images/overall_description.png b/docs/images/overall_description.png Binary files differnew file mode 100644 index 00000000..45aadf1b --- /dev/null +++ b/docs/images/overall_description.png diff --git a/docs/images/vPing.png b/docs/images/vPing.png Binary files differnew file mode 100644 index 00000000..fa223d13 --- /dev/null +++ b/docs/images/vPing.png 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() |