X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=tests%2Ftransportpce_tests%2Fcommon%2Ftest_utils.py;h=7f2cc1d33edd1f6c8a1aaeb46f6577871f4d893e;hb=78881abcc31dc039c374bcc15266030e8dabcf87;hp=b94c9de012a13a3298fb685af5d89179c8bd4376;hpb=f4d7679be9ffcc5ef14241cbfe9040c1c177b260;p=transportpce.git diff --git a/tests/transportpce_tests/common/test_utils.py b/tests/transportpce_tests/common/test_utils.py index b94c9de01..7f2cc1d33 100644 --- a/tests/transportpce_tests/common/test_utils.py +++ b/tests/transportpce_tests/common/test_utils.py @@ -9,6 +9,7 @@ ############################################################################## import json import os +import sys import re import signal import subprocess @@ -18,30 +19,46 @@ import requests import simulators -sims = simulators.sims -honeynode_executable = simulators.honeynode_executable -samples_directory = simulators.samples_directory +SIMS = simulators.SIMS +HONEYNODE_EXECUTABLE = simulators.HONEYNODE_EXECUTABLE +SAMPLES_DIRECTORY = simulators.SAMPLES_DIRECTORY -HONEYNODE_OK_START_MSG = re.escape("Netconf SSH endpoint started successfully at 0.0.0.0") -KARAF_OK_START_MSG = re.escape("Blueprint container for bundle " - "org.opendaylight.netconf.restconf") + ".* was successfully created" +HONEYNODE_OK_START_MSG = "Netconf SSH endpoint started successfully at 0.0.0.0" +KARAF_OK_START_MSG = re.escape( + "Blueprint container for bundle org.opendaylight.netconf.restconf")+".* was successfully created" -TYPE_APPLICATION_JSON = {'content-type': 'application/json'} -log_directory = os.path.dirname(os.path.realpath(__file__)) +RESTCONF_BASE_URL = "http://localhost:8181/restconf" +ODL_LOGIN = "admin" +ODL_PWD = "admin" +NODES_LOGIN = "admin" +NODES_PWD = "admin" -karaf_log = os.path.join( +TYPE_APPLICATION_JSON = {'Content-Type': 'application/json', 'Accept': 'application/json'} +TYPE_APPLICATION_XML = {'Content-Type': 'application/xml', 'Accept': 'application/xml'} + +CODE_SHOULD_BE_200 = 'Http status code should be 200' +CODE_SHOULD_BE_201 = 'Http status code should be 201' + +LOG_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) + +KARAF_LOG = os.path.join( os.path.dirname(os.path.realpath(__file__)), "..", "..", "..", "karaf", "target", "assembly", "data", "log", "karaf.log") process_list = [] +if "USE_LIGHTY" in os.environ and os.environ['USE_LIGHTY'] == 'True': + TPCE_LOG = 'odl.log' +else: + TPCE_LOG = KARAF_LOG + def start_sims(sims_list): for sim in sims_list: print("starting simulator for " + sim + "...") - log_file = os.path.join(log_directory, sims[sim]['logfile']) - process = start_honeynode(log_file, sims[sim]['port'], sims[sim]['configfile']) + log_file = os.path.join(LOG_DIRECTORY, SIMS[sim]['logfile']) + process = start_honeynode(log_file, SIMS[sim]['port'], SIMS[sim]['configfile']) if wait_until_log_contains(log_file, HONEYNODE_OK_START_MSG, 100): print("simulator for " + sim + " started") else: @@ -49,26 +66,26 @@ def start_sims(sims_list): shutdown_process(process) for pid in process_list: shutdown_process(pid) - exit(3) + sys.exit(3) process_list.append(process) return process_list def start_tpce(): - print("starting opendaylight...") + print("starting OpenDaylight...") if "USE_LIGHTY" in os.environ and os.environ['USE_LIGHTY'] == 'True': process = start_lighty() # TODO: add some sort of health check similar to Karaf below else: process = start_karaf() - if wait_until_log_contains(karaf_log, KARAF_OK_START_MSG, time_to_wait=60): - print("opendaylight started") + if wait_until_log_contains(KARAF_LOG, KARAF_OK_START_MSG, time_to_wait=60): + print("OpenDaylight started !") else: - print("opendaylight failed to start") + print("OpenDaylight failed to start !") shutdown_process(process) for pid in process_list: shutdown_process(pid) - exit(1) + sys.exit(1) process_list.append(process) return process_list @@ -122,16 +139,37 @@ def delete_request(url, username, password): auth=(username, password)) -def generate_connect_data(node_id: str, node_port: str): - data = {"node": [{ +def mount_device(node_id, sim): + url = ("{}/config/network-topology:network-topology/topology/topology-netconf/node/" + + node_id).format(RESTCONF_BASE_URL) + headers = {"node": [{ "node-id": node_id, - "netconf-node-topology:username": "admin", - "netconf-node-topology:password": "admin", + "netconf-node-topology:username": NODES_LOGIN, + "netconf-node-topology:password": NODES_PWD, "netconf-node-topology:host": "127.0.0.1", - "netconf-node-topology:port": node_port, + "netconf-node-topology:port": SIMS[sim]['port'], "netconf-node-topology:tcp-only": "false", "netconf-node-topology:pass-through": {}}]} - return data + response = put_request(url, headers, ODL_LOGIN, ODL_PWD) + if wait_until_log_contains(TPCE_LOG, re.escape("Triggering notification stream NETCONF for node "+node_id), 60): + print("Node "+node_id+" correctly added to tpce topology", end='... ', flush=True) + else: + print("Node "+node_id+" still not added to tpce topology", end='... ', flush=True) + if response.status_code == requests.codes.ok: + print("It was probably loaded at start-up", end='... ', flush=True) + # TODO an else-clause to abort test would probably be nice here + return response + + +def unmount_device(node_id): + url = ("{}/config/network-topology:network-topology/topology/topology-netconf/node/" + + node_id).format(RESTCONF_BASE_URL) + response = delete_request(url, ODL_LOGIN, ODL_PWD) + if wait_until_log_contains(TPCE_LOG, re.escape("onDeviceDisConnected: "+node_id), 60): + print("Node "+node_id+" correctly deleted from tpce topology", end='... ', flush=True) + else: + print("Node "+node_id+" still not deleted from tpce topology", end='... ', flush=True) + return response def generate_link_data(xpdr_node: str, xpdr_num: str, network_num: str, rdm_node: str, srg_num: str, @@ -160,40 +198,41 @@ def shutdown_process(process): def start_honeynode(log_file: str, node_port: str, node_config_file_name: str): - if os.path.isfile(honeynode_executable): + if os.path.isfile(HONEYNODE_EXECUTABLE): with open(log_file, 'w') as outfile: return subprocess.Popen( - [honeynode_executable, node_port, os.path.join(samples_directory, node_config_file_name)], + [HONEYNODE_EXECUTABLE, node_port, os.path.join(SAMPLES_DIRECTORY, node_config_file_name)], stdout=outfile, stderr=outfile) -def wait_until_log_contains(log_file, searched_string, time_to_wait=20): +def wait_until_log_contains(log_file, regexp, time_to_wait=20): found = False tail = None try: - with timeout(seconds=time_to_wait): - print("Waiting for " + searched_string) + with TimeOut(seconds=time_to_wait): + print("Searching for pattern '"+regexp+"' in "+os.path.basename(log_file), end='... ', flush=True) tail = subprocess.Popen(['tail', '-F', log_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - regexp = re.compile(searched_string) + compiled_regexp = re.compile(regexp) while True: line = tail.stdout.readline().decode('utf-8') - if regexp.search(line): - print("Searched string found.") + if compiled_regexp.search(line): + print("String found!", end=' ') found = True break except TimeoutError: - print("Cannot find string "+searched_string+" after waiting for "+str(time_to_wait)) + print("String not found after "+str(time_to_wait), end=" seconds! ", flush=True) finally: if tail is not None: - print("Stopping tail command") + print("Stopping tail command", end='... ', flush=True) tail.stderr.close() tail.stdout.close() tail.kill() tail.wait() return found +# TODO try to find an alternative to subprocess+tail -f (such as https://pypi.org/project/tailhead/) -class timeout: +class TimeOut: def __init__(self, seconds=1, error_message='Timeout'): self.seconds = seconds self.error_message = error_message