diff options
-rwxr-xr-x | docker/run_tests.sh | 25 | ||||
-rw-r--r-- | docs/userguide/runfunctest.rst | 5 | ||||
-rw-r--r-- | testcases/Controllers/ODL/CI/odlreport2db.py | 1 | ||||
-rw-r--r-- | testcases/Controllers/ONOS/Teston/CI/onosfunctest.py | 1 | ||||
-rwxr-xr-x | testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py | 18 | ||||
-rwxr-xr-x | testcases/VIM/OpenStack/CI/libraries/run_rally.py | 6 | ||||
-rw-r--r-- | testcases/VIM/OpenStack/CI/libraries/run_tempest.py | 20 | ||||
-rw-r--r-- | testcases/features/doctor.py | 2 | ||||
-rw-r--r-- | testcases/functest_utils.py | 94 | ||||
-rw-r--r-- | testcases/vIMS/CI/vIMS.py | 9 | ||||
-rw-r--r-- | testcases/vPing/CI/libraries/vPing_ssh.py | 7 | ||||
-rw-r--r-- | testcases/vPing/CI/libraries/vPing_userdata.py | 7 |
12 files changed, 130 insertions, 65 deletions
diff --git a/docker/run_tests.sh b/docker/run_tests.sh index 7dc7f058..0f9e8a30 100755 --- a/docker/run_tests.sh +++ b/docker/run_tests.sh @@ -22,6 +22,7 @@ where: -h|--help show this help text -r|--report push results to database (false by default) -n|--no-clean do not clean OpenStack resources after test run + -s|--serial run tests in one thread -t|--test run specific set of tests <test_name> one or more of the following separated by comma: vping_ssh,vping_userdata,odl,rally,tempest,vims,onos,promise,ovno @@ -38,6 +39,8 @@ examples: offline=false report="" clean=true +serial=false + # Get the list of runnable tests # Check if we are in CI mode @@ -82,16 +85,25 @@ function run_test(){ echo " Running test case: $i" echo "----------------------------------------------" echo "" + clean_flag="" + if [ $clean == "false" ]; then + clean_flag="-n" + fi + serial_flag="" + if [ $serial == "true" ]; then + serial_flag="-s" + fi + case $test_name in "vping_ssh") info "Running vPing-SSH test..." python ${FUNCTEST_REPO_DIR}/testcases/vPing/CI/libraries/vPing_ssh.py \ - --debug ${report} + --debug $clean_flag ${report} ;; "vping_userdata") info "Running vPing-userdata test... " python ${FUNCTEST_REPO_DIR}/testcases/vPing/CI/libraries/vPing_userdata.py \ - --debug ${report} + --debug $clean_flag ${report} ;; "odl") info "Running ODL test..." @@ -110,7 +122,7 @@ function run_test(){ "tempest") info "Running Tempest tests..." python ${FUNCTEST_REPO_DIR}/testcases/VIM/OpenStack/CI/libraries/run_tempest.py \ - --debug -m custom ${report} + --debug $serial_flag $clean_flag -m custom ${report} # save tempest.conf for further troubleshooting tempest_conf="${RALLY_VENV_DIR}/tempest/for-deployment-*/tempest.conf" if [ -f ${tempest_conf} ]; then @@ -121,13 +133,13 @@ function run_test(){ "vims") info "Running vIMS test..." python ${FUNCTEST_REPO_DIR}/testcases/vIMS/CI/vIMS.py \ - --debug ${report} + --debug $clean_flag ${report} clean_openstack ;; "rally") info "Running Rally benchmark suite..." python ${FUNCTEST_REPO_DIR}/testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py \ - --debug all ${report} + --debug $clean_flag all ${report} clean_openstack ;; @@ -208,6 +220,9 @@ while [[ $# > 0 ]] -n|--no-clean) clean=false ;; + -s|--serial) + serial=true + ;; -t|--test|--tests) TEST="$2" shift diff --git a/docs/userguide/runfunctest.rst b/docs/userguide/runfunctest.rst index 61511413..36433374 100644 --- a/docs/userguide/runfunctest.rst +++ b/docs/userguide/runfunctest.rst @@ -26,6 +26,7 @@ several options:: -h|--help show this help text -r|--report push results to database (false by default) -n|--no-clean do not clean up OpenStack resources after test run + -s|--serial run tests in one thread -t|--test run specific set of tests <test_name> one or more of the following separated by comma: vping_ssh,vping_userdata,odl,rally,tempest,vims,onos,promise,ovno @@ -58,6 +59,10 @@ is called once by *prepare_env.sh* when setting up the Functest environment to snapshot all the OpenStack resources (images, networks, volumes, security groups, tenants, users) so that an eventual cleanup does not remove any of this defaults. +The *-s* option forces execution of test cases in a single thread. Currently this +option affects Tempest test cases only and can be used e.g. for troubleshooting +concurrency problems. + The script *$repos_dir/functest/testcases/VIM/OpenStack/CI/libraries/clean_openstack.py* is normally called after a test execution if the *-n* is not specified. It diff --git a/testcases/Controllers/ODL/CI/odlreport2db.py b/testcases/Controllers/ODL/CI/odlreport2db.py index 1538f79c..47067963 100644 --- a/testcases/Controllers/ODL/CI/odlreport2db.py +++ b/testcases/Controllers/ODL/CI/odlreport2db.py @@ -130,6 +130,7 @@ def main(argv): # -p opnfv-jump-2 # -s os-odl_l2-ha functest_utils.push_results_to_db(database, + "functest", data['case_name'], None, data['pod_name'], diff --git a/testcases/Controllers/ONOS/Teston/CI/onosfunctest.py b/testcases/Controllers/ONOS/Teston/CI/onosfunctest.py index bf031cb4..dc45088b 100644 --- a/testcases/Controllers/ONOS/Teston/CI/onosfunctest.py +++ b/testcases/Controllers/ONOS/Teston/CI/onosfunctest.py @@ -182,6 +182,7 @@ def main(): pod_name = functest_utils.get_pod_name(logger) result = GetResult() functest_utils.push_results_to_db(TEST_DB, + "functest", "ONOS", logger, pod_name, scenario, payload=result) diff --git a/testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py b/testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py index e1870046..0d199260 100755 --- a/testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py +++ b/testcases/VIM/OpenStack/CI/libraries/run_rally-cert.py @@ -54,6 +54,9 @@ parser.add_argument("-s", "--smoke", parser.add_argument("-v", "--verbose", help="Print verbose info about the progress", action="store_true") +parser.add_argument("-n", "--noclean", + help="Don't clean the created resources for this test.", + action="store_true") args = parser.parse_args() @@ -428,8 +431,10 @@ def main(): report += ""\ "| " + name + " | " + duration + " | " + nb_tests + " | " + success + "|\n"\ "+-------------------+------------+---------------+-----------+\n" - payload.append({'module': name, 'duration': duration, - 'nb tests': nb_tests, 'success': success}) + payload.append({'module': name, + 'details': {'duration': s['overall_duration'], + 'nb tests': s['nb_tests'], + 'success': s['success']}}) total_duration_str = time.strftime("%H:%M:%S", time.gmtime(total_duration)) total_duration_str2 = "{0:<10}".format(total_duration_str) @@ -442,9 +447,9 @@ def main(): report += "+===================+============+===============+===========+\n" logger.info("\n"+report) - payload.append({'summary': {'duration': total_duration_str2, - 'nb tests': total_nb_tests_str, - 'nb success': total_success_str}}) + payload.append({'summary': {'duration': total_duration, + 'nb tests': total_nb_tests, + 'nb success': total_success}}) # Generate json results for DB #json_results = {"timestart": time_start, "duration": total_duration, @@ -455,6 +460,9 @@ def main(): logger.debug("Pushing Rally summary into DB...") push_results_to_db("Rally", payload) + if args.noclean: + exit(0) + logger.debug("Deleting image '%s' with ID '%s'..." \ % (GLANCE_IMAGE_NAME, image_id)) if not functest_utils.delete_glance_image(nova_client, image_id): diff --git a/testcases/VIM/OpenStack/CI/libraries/run_rally.py b/testcases/VIM/OpenStack/CI/libraries/run_rally.py index 18f60acc..6b1aae2e 100755 --- a/testcases/VIM/OpenStack/CI/libraries/run_rally.py +++ b/testcases/VIM/OpenStack/CI/libraries/run_rally.py @@ -47,6 +47,9 @@ parser.add_argument("-r", "--report", parser.add_argument("-v", "--verbose", help="Print verbose info about the progress", action="store_true") +parser.add_argument("-n", "--noclean", + help="Don't clean the created resources for this test.", + action="store_true") args = parser.parse_args() @@ -271,6 +274,9 @@ def main(): print(args.test_name) run_task(args.test_name) + if args.noclean: + exit(0) + logger.debug("Deleting image '%s' with ID '%s'..." \ % (GLANCE_IMAGE_NAME, image_id)) if not functest_utils.delete_glance_image(nova_client, image_id): diff --git a/testcases/VIM/OpenStack/CI/libraries/run_tempest.py b/testcases/VIM/OpenStack/CI/libraries/run_tempest.py index b8ed2716..29466918 100644 --- a/testcases/VIM/OpenStack/CI/libraries/run_tempest.py +++ b/testcases/VIM/OpenStack/CI/libraries/run_tempest.py @@ -33,12 +33,21 @@ modes = ['full', 'smoke', 'baremetal', 'compute', 'data_processing', """ tests configuration """ parser = argparse.ArgumentParser() -parser.add_argument("-d", "--debug", help="Debug mode", action="store_true") -parser.add_argument("-m", "--mode", help="Tempest test mode [smoke, all]", +parser.add_argument("-d", "--debug", + help="Debug mode", + action="store_true") +parser.add_argument("-s", "--serial", + help="Run tests in one thread", + action="store_true") +parser.add_argument("-m", "--mode", + help="Tempest test mode [smoke, all]", default="smoke") parser.add_argument("-r", "--report", help="Create json result file", action="store_true") +parser.add_argument("-n", "--noclean", + help="Don't clean the created resources for this test.", + action="store_true") args = parser.parse_args() @@ -289,12 +298,19 @@ def main(): else: MODE = "--set "+args.mode + if args.serial: + MODE = "--concur 1 "+MODE + if not os.path.exists(TEMPEST_RESULTS_DIR): os.makedirs(TEMPEST_RESULTS_DIR) create_tempest_resources() configure_tempest() run_tempest(MODE) + + if args.noclean: + exit(0) + free_tempest_resources() diff --git a/testcases/features/doctor.py b/testcases/features/doctor.py index 8eb85a80..5669a990 100644 --- a/testcases/features/doctor.py +++ b/testcases/features/doctor.py @@ -71,7 +71,7 @@ def main(): 'd': details, }) functest_utils.push_results_to_db(TEST_DB_URL, - 'doctor-notification', + 'doctor','doctor-notification', logger, pod_name, scenario, details) diff --git a/testcases/functest_utils.py b/testcases/functest_utils.py index 57ec1863..94a4fa8a 100644 --- a/testcases/functest_utils.py +++ b/testcases/functest_utils.py @@ -18,7 +18,6 @@ import socket import subprocess import sys import urllib2 -import yaml from git import Repo @@ -39,6 +38,7 @@ def check_credentials(): env_vars = ['OS_AUTH_URL', 'OS_USERNAME', 'OS_PASSWORD', 'OS_TENANT_NAME'] return all(map(lambda v: v in os.environ and os.environ[v], env_vars)) + def get_credentials(service): """Returns a creds dictionary filled with the following keys: * username @@ -70,7 +70,6 @@ def get_credentials(service): return creds - #********************************************* # NOVA #********************************************* @@ -134,10 +133,10 @@ def get_floating_ips(nova_client): def create_flavor(nova_client, flavor_name, ram, disk, vcpus): try: - flavor = nova_client.flavors.create(flavor_name,ram,vcpus,disk) + flavor = nova_client.flavors.create(flavor_name, ram, vcpus, disk) except Exception, e: print "Error [create_flavor(nova_client, '%s', '%s', '%s', "\ - "'%s')]:" %(flavor_name,ram, disk, vcpus), e + "'%s')]:" % (flavor_name, ram, disk, vcpus), e return None return flavor.id @@ -156,7 +155,7 @@ def create_floating_ip(neutron_client): def add_floating_ip(nova_client, server_id, floatingip_id): try: - nova_client.servers.add_floating_ip(server_id,floatingip_id) + nova_client.servers.add_floating_ip(server_id, floatingip_id) return True except Exception, e: print "Error [add_floating_ip(nova_client, '%s', '%s')]:" % \ @@ -182,8 +181,6 @@ def delete_floating_ip(nova_client, floatingip_id): return False - - #********************************************* # NEUTRON #********************************************* @@ -274,7 +271,7 @@ def create_neutron_subnet(neutron_client, name, cidr, net_id): return subnet['subnets'][0]['id'] except Exception, e: print "Error [create_neutron_subnet(neutron_client, '%s', '%s', "\ - "'%s')]:" %(name,cidr, net_id), e + "'%s')]:" % (name, cidr, net_id), e return False @@ -300,7 +297,7 @@ def create_neutron_port(neutron_client, name, network_id, ip): return port['port']['id'] except Exception, e: print "Error [create_neutron_port(neutron_client, '%s', '%s', "\ - "'%s')]:" %(name,network_id, ip), e + "'%s')]:" % (name, network_id, ip), e return False @@ -311,7 +308,7 @@ def update_neutron_net(neutron_client, network_id, shared=False): return True except Exception, e: print "Error [update_neutron_net(neutron_client, '%s', '%s')]:" % \ - (network_id,str(shared)), e + (network_id, str(shared)), e return False @@ -325,7 +322,7 @@ def update_neutron_port(neutron_client, port_id, device_owner): return port['port']['id'] except Exception, e: print "Error [update_neutron_port(neutron_client, '%s', '%s')]:" % \ - (port_id,device_owner), e + (port_id, device_owner), e return False @@ -336,14 +333,15 @@ def add_interface_router(neutron_client, router_id, subnet_id): return True except Exception, e: print "Error [add_interface_router(neutron_client, '%s', '%s')]:" % \ - (router_id,subnet_id), e + (router_id, subnet_id), e return False + def add_gateway_router(neutron_client, router_id): ext_net_id = get_external_net_id(neutron_client) router_dict = {'network_id': ext_net_id} try: - neutron_client.add_gateway_router(router_id,router_dict) + neutron_client.add_gateway_router(router_id, router_dict) return True except Exception, e: print "Error [add_gateway_router(neutron_client, '%s')]:" % router_id, e @@ -396,7 +394,7 @@ def remove_interface_router(neutron_client, router_id, subnet_id): return True except Exception, e: print "Error [remove_interface_router(neutron_client, '%s', '%s')]:" % \ - (router_id,subnet_id), e + (router_id, subnet_id), e return False @@ -409,7 +407,6 @@ def remove_gateway_router(neutron_client, router_id): return False - #********************************************* # SEC GROUPS #********************************************* @@ -424,44 +421,43 @@ def get_security_groups(neutron_client): def create_security_group(neutron_client, sg_name, sg_description): - json_body= {'security_group' : { 'name' : sg_name, \ - 'description' : sg_description }} + json_body = {'security_group': {'name': sg_name, + 'description': sg_description}} try: secgroup = neutron_client.create_security_group(json_body) return secgroup['security_group'] except Exception, e: print "Error [create_security_group(neutron_client, '%s', '%s')]:" % \ - (sg_name,sg_description), e + (sg_name, sg_description), e return False def create_secgroup_rule(neutron_client, sg_id, direction, protocol, - port_range_min = None, port_range_max = None): - if port_range_min == None and port_range_max == None: - json_body = { 'security_group_rule' : \ - { 'direction' : direction, \ - 'security_group_id' : sg_id, \ - 'protocol' : protocol } } - elif port_range_min != None and port_range_max != None: - json_body = { 'security_group_rule' : \ - { 'direction' : direction, \ - 'security_group_id' : sg_id, \ - 'port_range_min': port_range_min, \ - 'port_range_max' : port_range_max, \ - 'protocol' : protocol } } + port_range_min=None, port_range_max=None): + if port_range_min is None and port_range_max is None: + json_body = {'security_group_rule': {'direction': direction, + 'security_group_id': sg_id, + 'protocol': protocol}} + elif port_range_min is not None and port_range_max is not None: + json_body = {'security_group_rule': {'direction': direction, + 'security_group_id': sg_id, + 'port_range_min': port_range_min, + 'port_range_max': port_range_max, + 'protocol': protocol}} else: print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\ - "'%s', '%s', '%s', '%s')]:" %(neutron_client, sg_id, direction, \ - port_range_min, port_range_max, protocol),\ - " Invalid values for port_range_min, port_range_max" + "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction, \ + port_range_min, port_range_max, protocol),\ + " Invalid values for port_range_min, port_range_max" return False try: neutron_client.create_security_group_rule(json_body) return True except Exception, e: print "Error [create_secgroup_rule(neutron_client, '%s', '%s', "\ - "'%s', '%s', '%s', '%s')]:" %(neutron_client, sg_id, direction, \ - port_range_min, port_range_max, protocol), e + "'%s', '%s', '%s', '%s')]:" % (neutron_client, sg_id, direction, + port_range_min, port_range_max, + protocol), e return False @@ -487,7 +483,7 @@ def update_sg_quota(neutron_client, tenant_id, sg_quota, sg_rule_quota): return True except Exception, e: print "Error [update_sg_quota(neutron_client, '%s', '%s', "\ - "'%s')]:" %(tenant_id, sg_quota, sg_rule_quota), e + "'%s')]:" % (tenant_id, sg_quota, sg_rule_quota), e return False @@ -500,8 +496,6 @@ def delete_security_group(neutron_client, secgroup_id): return False - - #********************************************* # GLANCE #********************************************* @@ -538,7 +532,7 @@ def create_glance_image(glance_client, image_name, file_path, public=True): return image.id except Exception, e: print "Error [create_glance_image(glance_client, '%s', '%s', "\ - "'%s')]:" %(image_name, file_path, str(public)), e + "'%s')]:" % (image_name, file_path, str(public)), e return False @@ -551,7 +545,6 @@ def delete_glance_image(nova_client, image_id): return False - #********************************************* # CINDER #********************************************* @@ -594,11 +587,11 @@ def update_cinder_quota(cinder_client, tenant_id, vols_quota, try: quotas_default = cinder_client.quotas.update(tenant_id, - **quotas_values) + **quotas_values) return True except Exception, e: print "Error [update_cinder_quota(cinder_client, '%s', '%s', '%s'" \ - "'%s')]:" %(tenant_id, vols_quota, snapshots_quota, gigabytes_quota), e + "'%s')]:" % (tenant_id, vols_quota, snapshots_quota, gigabytes_quota), e return False @@ -628,7 +621,6 @@ def delete_volume_type(cinder_client, volume_type): return False - #********************************************* # KEYSTONE #********************************************* @@ -701,7 +693,7 @@ def create_user(keystone_client, user_name, user_password, return user.id except Exception, e: print "Error [create_user(keystone_client, '%s', '%s', '%s'" \ - "'%s')]:" %(user_name, user_password, user_email, tenant_id), e + "'%s')]:" % (user_name, user_password, user_email, tenant_id), e return False @@ -711,7 +703,7 @@ def add_role_user(keystone_client, user_id, role_id, tenant_id): return True except Exception, e: print "Error [add_role_user(keystone_client, '%s', '%s'" \ - "'%s')]:" %(user_id, role_id, tenant_id), e + "'%s')]:" % (user_id, role_id, tenant_id), e return False @@ -827,14 +819,14 @@ def get_pod_name(logger=None): return "unknown-pod" -def push_results_to_db(db_url, case_name, logger, pod_name, +def push_results_to_db(db_url, project, case_name, logger, pod_name, version, payload): """ POST results to the Result target DB """ url = db_url + "/results" installer = get_installer_type(logger) - params = {"project_name": "functest", "case_name": case_name, + params = {"project_name": project, "case_name": case_name, "pod_name": pod_name, "installer": installer, "version": version, "details": payload} @@ -845,8 +837,8 @@ def push_results_to_db(db_url, case_name, logger, pod_name, logger.debug(r) return True except Exception, e: - print "Error [push_results_to_db('%s', '%s', '%s', '%s', '%s')]:" \ - % (db_url, case_name, pod_name, version, payload), e + print "Error [push_results_to_db('%s', '%s', '%s', '%s', '%s', '%s')]:" \ + % (db_url, project, case_name, pod_name, version, payload), e return False @@ -861,7 +853,7 @@ def get_resolvconf_ns(): ip = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b", line) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if ip: - result = sock.connect_ex((ip.group(),53)) + result = sock.connect_ex((ip.group(), 53)) if result == 0: nameservers.append(ip.group()) line = rconf.readline() diff --git a/testcases/vIMS/CI/vIMS.py b/testcases/vIMS/CI/vIMS.py index a8ac97f5..1746d38b 100644 --- a/testcases/vIMS/CI/vIMS.py +++ b/testcases/vIMS/CI/vIMS.py @@ -40,6 +40,9 @@ parser.add_argument("-d", "--debug", help="Debug mode", action="store_true") parser.add_argument("-r", "--report", help="Create json result file", action="store_true") +parser.add_argument("-n", "--noclean", + help="Don't clean the created resources for this test.", + action="store_true") args = parser.parse_args() """ logging configuration """ @@ -134,7 +137,9 @@ def push_results(): scenario = functest_utils.get_scenario(logger) pod_name = functest_utils.get_pod_name(logger) - functest_utils.push_results_to_db(db_url=DB_URL, case_name="vIMS", + functest_utils.push_results_to_db(db_url=DB_URL, + project="functest", + case_name="vIMS", logger=logger, pod_name=pod_name, version=scenario, payload=RESULTS) @@ -461,6 +466,8 @@ def main(): cfy.undeploy_manager() ############### GENERAL CLEANUP ################ + if args.noclean: + exit(0) ks_creds = functest_utils.get_credentials("keystone") diff --git a/testcases/vPing/CI/libraries/vPing_ssh.py b/testcases/vPing/CI/libraries/vPing_ssh.py index 9c83c80e..3050aad5 100644 --- a/testcases/vPing/CI/libraries/vPing_ssh.py +++ b/testcases/vPing/CI/libraries/vPing_ssh.py @@ -37,6 +37,9 @@ parser.add_argument("-d", "--debug", help="Debug mode", action="store_true") parser.add_argument("-r", "--report", help="Create json result file", action="store_true") +parser.add_argument("-n", "--noclean", + help="Don't clean the created resources for this test.", + action="store_true") args = parser.parse_args() @@ -198,6 +201,9 @@ def create_private_neutron_net(neutron): def cleanup(nova, neutron, image_id, network_dic, port_id1, port_id2, secgroup_id): + if args.noclean: + logger.debug("The OpenStack resources are not deleted.") + return True # delete both VMs logger.info("Cleaning up...") @@ -288,6 +294,7 @@ def push_results(start_time_ts, duration, test_status): scenario = functest_utils.get_scenario(logger) pod_name = functest_utils.get_pod_name(logger) functest_utils.push_results_to_db(TEST_DB, + "functest", "vPing", logger, pod_name, scenario, payload={'timestart': start_time_ts, diff --git a/testcases/vPing/CI/libraries/vPing_userdata.py b/testcases/vPing/CI/libraries/vPing_userdata.py index be1ed3f8..90562969 100644 --- a/testcases/vPing/CI/libraries/vPing_userdata.py +++ b/testcases/vPing/CI/libraries/vPing_userdata.py @@ -35,6 +35,9 @@ parser.add_argument("-d", "--debug", help="Debug mode", action="store_true") parser.add_argument("-r", "--report", help="Create json result file", action="store_true") +parser.add_argument("-n", "--noclean", + help="Don't clean the created resources for this test.", + action="store_true") args = parser.parse_args() @@ -192,6 +195,9 @@ def create_private_neutron_net(neutron): def cleanup(nova, neutron, image_id, network_dic, port_id1, port_id2): + if args.noclean: + logger.debug("The OpenStack resources are not deleted.") + return True # delete both VMs logger.info("Cleaning up...") @@ -276,6 +282,7 @@ def push_results(start_time_ts, duration, test_status): scenario = functest_utils.get_scenario(logger) pod_name = functest_utils.get_pod_name(logger) functest_utils.push_results_to_db(TEST_DB, + "functest", "vPing_userdata", logger, pod_name, scenario, payload={'timestart': start_time_ts, |