From: Ryota Mibu Date: Fri, 22 Sep 2017 11:25:35 +0000 (+0000) Subject: Merge "Add parallel execution and shortcut notification to inspector design guideline" X-Git-Tag: opnfv-6.0.0~40 X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=commitdiff_plain;h=079ac9a481fcc1baa53cb5ab2896bbe037585f3b;hp=1f00955295c2461a181aa1fa5d8587f12832bf4d;p=doctor.git Merge "Add parallel execution and shortcut notification to inspector design guideline" --- diff --git a/.gitignore b/.gitignore index c671eeed..7e893869 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ *.pyc .*.sw? **.log +*.pyc +/*.egg-info/ +/build/ /docs_build/ /docs_output/ /releng/ diff --git a/docs/development/overview/testing.rst b/docs/development/overview/testing.rst index cd39ee03..08a4d933 100644 --- a/docs/development/overview/testing.rst +++ b/docs/development/overview/testing.rst @@ -29,7 +29,10 @@ OpenStack services. .. _OpenStack CLI manual: https://docs.openstack.org/user-guide/common/cli-set-environment-variables-using-openstack-rc.html -Then, you can run the script as follows: +Run Bash Test Script +~~~~~~~~~~~~~~~~~~~~ + +You can run the bash script as follows: .. code-block:: bash @@ -46,6 +49,24 @@ INSPECTOR_TYPE can be specified either 'sample'(default) or 'congress'. For testing with stable version, checkout stable branch of doctor repo before './run.sh'. +The bash test script will be deprecated(only bug fixes) after E Release. + +Run Python Test Script +~~~~~~~~~~~~~~~~~~~~~~ + +You can run the python script as follows: + +.. code-block:: bash + + git clone https://gerrit.opnfv.org/gerrit/doctor + cd doctor && tox + +You can see all the configurations with default values in sample configuration +file `doctor.sample.conf`_. And you can also modify the file to meet your +environment and then run the test. + +.. _doctor.sample.conf: https://git.opnfv.org/doctor/tree/etc/doctor.sample.conf + Run Functest Suite ================== @@ -60,10 +81,14 @@ Functest container. You can run the Doctor test with the following steps: -e INSTALLER_TYPE=${INSTALLER_TYPE} \ -e INSTALLER_IP=${INSTALLER_IP} \ -e INSPECTOR_TYPE=sample \ + -e PYTHON_ENABLE=True \ opnfv/functest:${DOCKER_TAG} /bin/bash docker exec python /home/opnfv/repos/functest/functest/ci/prepare_env.py start docker exec functest testcase run doctor +Add an environment variable *PYTHON_ENABLE* to indicate that using Python or +Bash to run the test when start the docker container. + See `Functest Userguide`_ for more information. .. _Functest Userguide: http://artifacts.opnfv.org/functest/docs/userguide/index.html diff --git a/tests/scenario/__init__.py b/doctor_tests/__init__.py similarity index 100% rename from tests/scenario/__init__.py rename to doctor_tests/__init__.py diff --git a/tests/alarm.py b/doctor_tests/alarm.py similarity index 94% rename from tests/alarm.py rename to doctor_tests/alarm.py index 916f4405..3b1aaf3f 100644 --- a/tests/alarm.py +++ b/doctor_tests/alarm.py @@ -8,10 +8,10 @@ ############################################################################## from oslo_config import cfg -from identity_auth import get_identity_auth -from identity_auth import get_session -from os_clients import aodh_client -from os_clients import nova_client +from doctor_tests.identity_auth import get_identity_auth +from doctor_tests.identity_auth import get_session +from doctor_tests.os_clients import aodh_client +from doctor_tests.os_clients import nova_client OPTS = [ cfg.StrOpt('alarm_basename', diff --git a/tests/common/__init__.py b/doctor_tests/common/__init__.py similarity index 100% rename from tests/common/__init__.py rename to doctor_tests/common/__init__.py diff --git a/tests/common/constants.py b/doctor_tests/common/constants.py similarity index 100% rename from tests/common/constants.py rename to doctor_tests/common/constants.py diff --git a/tests/common/utils.py b/doctor_tests/common/utils.py similarity index 100% rename from tests/common/utils.py rename to doctor_tests/common/utils.py diff --git a/tests/config.py b/doctor_tests/config.py similarity index 75% rename from tests/config.py rename to doctor_tests/config.py index c71d5ad7..273e84d5 100644 --- a/tests/config.py +++ b/doctor_tests/config.py @@ -10,17 +10,17 @@ import itertools from oslo_config import cfg -import alarm -import consumer -import image -import instance -import installer -import network -import inspector -import monitor -import os_clients -import profiler_poc -import user +from doctor_tests import alarm +from doctor_tests import consumer +from doctor_tests import image +from doctor_tests import instance +from doctor_tests import installer +from doctor_tests import network +from doctor_tests import inspector +from doctor_tests import monitor +from doctor_tests import os_clients +from doctor_tests import profiler_poc +from doctor_tests import user def list_opts(): diff --git a/tests/consumer/__init__.py b/doctor_tests/consumer/__init__.py similarity index 89% rename from tests/consumer/__init__.py rename to doctor_tests/consumer/__init__.py index ccec8644..2c66a547 100644 --- a/tests/consumer/__init__.py +++ b/doctor_tests/consumer/__init__.py @@ -28,10 +28,10 @@ OPTS = [ _consumer_name_class_mapping = { - 'sample': 'consumer.sample.SampleConsumer' + 'sample': 'doctor_tests.consumer.sample.SampleConsumer' } def get_consumer(conf, log): consumer_class = _consumer_name_class_mapping.get(conf.consumer.type) - return importutils.import_object(consumer_class, conf, log) \ No newline at end of file + return importutils.import_object(consumer_class, conf, log) diff --git a/tests/consumer/base.py b/doctor_tests/consumer/base.py similarity index 100% rename from tests/consumer/base.py rename to doctor_tests/consumer/base.py diff --git a/tests/consumer/sample.py b/doctor_tests/consumer/sample.py similarity index 95% rename from tests/consumer/sample.py rename to doctor_tests/consumer/sample.py index 20ad9d57..d76a764b 100644 --- a/tests/consumer/sample.py +++ b/doctor_tests/consumer/sample.py @@ -13,7 +13,7 @@ import time from threading import Thread import requests -from consumer.base import BaseConsumer +from doctor_tests.consumer.base import BaseConsumer class SampleConsumer(BaseConsumer): @@ -68,4 +68,4 @@ class ConsumerApp(Thread): func() return 'consumer app shutting down...' - app.run(host="0.0.0.0", port=self.port) \ No newline at end of file + app.run(host="0.0.0.0", port=self.port) diff --git a/tests/identity_auth.py b/doctor_tests/identity_auth.py similarity index 99% rename from tests/identity_auth.py rename to doctor_tests/identity_auth.py index c94893f4..2586720c 100644 --- a/tests/identity_auth.py +++ b/doctor_tests/identity_auth.py @@ -6,7 +6,6 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## - import os from keystoneauth1 import loading diff --git a/tests/image.py b/doctor_tests/image.py similarity index 96% rename from tests/image.py rename to doctor_tests/image.py index 453322b8..2e313e12 100644 --- a/tests/image.py +++ b/doctor_tests/image.py @@ -11,8 +11,8 @@ import urllib.request from oslo_config import cfg -from identity_auth import get_session -from os_clients import glance_client +from doctor_tests.identity_auth import get_session +from doctor_tests.os_clients import glance_client OPTS = [ cfg.StrOpt('image_name', diff --git a/tests/inspector/__init__.py b/doctor_tests/inspector/__init__.py similarity index 90% rename from tests/inspector/__init__.py rename to doctor_tests/inspector/__init__.py index afba4800..3be79e57 100644 --- a/tests/inspector/__init__.py +++ b/doctor_tests/inspector/__init__.py @@ -30,8 +30,8 @@ OPTS = [ _inspector_name_class_mapping = { - 'sample': 'inspector.sample.SampleInspector', - 'congress': 'inspector.congress.CongressInspector', + 'sample': 'doctor_tests.inspector.sample.SampleInspector', + 'congress': 'doctor_tests.inspector.congress.CongressInspector', } diff --git a/tests/inspector/base.py b/doctor_tests/inspector/base.py similarity index 100% rename from tests/inspector/base.py rename to doctor_tests/inspector/base.py diff --git a/tests/inspector/congress.py b/doctor_tests/inspector/congress.py similarity index 94% rename from tests/inspector/congress.py rename to doctor_tests/inspector/congress.py index ae295852..c89a41bd 100644 --- a/tests/inspector/congress.py +++ b/doctor_tests/inspector/congress.py @@ -6,11 +6,11 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from identity_auth import get_identity_auth -from identity_auth import get_session -from os_clients import congress_client +from doctor_tests.identity_auth import get_identity_auth +from doctor_tests.identity_auth import get_session +from doctor_tests.os_clients import congress_client -from inspector.base import BaseInspector +from doctor_tests.inspector.base import BaseInspector class CongressInspector(BaseInspector): diff --git a/tests/inspector/sample.py b/doctor_tests/inspector/sample.py similarity index 95% rename from tests/inspector/sample.py rename to doctor_tests/inspector/sample.py index 1c05cede..114e4ebd 100644 --- a/tests/inspector/sample.py +++ b/doctor_tests/inspector/sample.py @@ -14,12 +14,12 @@ import time from threading import Thread import requests -from common import utils -from identity_auth import get_identity_auth -from identity_auth import get_session -from os_clients import nova_client -from os_clients import neutron_client -from inspector.base import BaseInspector +from doctor_tests.common import utils +from doctor_tests.identity_auth import get_identity_auth +from doctor_tests.identity_auth import get_session +from doctor_tests.os_clients import nova_client +from doctor_tests.os_clients import neutron_client +from doctor_tests.inspector.base import BaseInspector class SampleInspector(BaseInspector): diff --git a/tests/installer/__init__.py b/doctor_tests/installer/__init__.py similarity index 91% rename from tests/installer/__init__.py rename to doctor_tests/installer/__init__.py index bb0e452d..02735b11 100644 --- a/tests/installer/__init__.py +++ b/doctor_tests/installer/__init__.py @@ -28,11 +28,11 @@ OPTS = [ _installer_name_class_mapping = { - 'local': 'installer.local.LocalInstaller', - 'apex': 'installer.apex.ApexInstaller' + 'local': 'doctor_tests.installer.local.LocalInstaller', + 'apex': 'doctor_tests.installer.apex.ApexInstaller' } def get_installer(conf, log): installer_class = _installer_name_class_mapping[conf.installer.type] - return importutils.import_object(installer_class, conf, log) \ No newline at end of file + return importutils.import_object(installer_class, conf, log) diff --git a/tests/installer/apex.py b/doctor_tests/installer/apex.py similarity index 97% rename from tests/installer/apex.py rename to doctor_tests/installer/apex.py index 98eb6c9c..2a1ce94b 100644 --- a/tests/installer/apex.py +++ b/doctor_tests/installer/apex.py @@ -12,10 +12,9 @@ import os import pwd import stat import subprocess -import sys -from common.utils import SSHClient -from installer.base import BaseInstaller +from doctor_tests.common.utils import SSHClient +from doctor_tests.installer.base import BaseInstaller class ApexInstaller(BaseInstaller): @@ -59,7 +58,7 @@ class ApexInstaller(BaseInstaller): gid = grp.getgrnam(user).gr_gid os.chown('./instack_key', uid, gid) os.chmod('./instack_key', stat.S_IREAD) - current_dir = sys.path[0] + current_dir = os.curdir self.key_file = '{0}/{1}'.format(current_dir, 'instack_key') return self.key_file diff --git a/tests/installer/base.py b/doctor_tests/installer/base.py similarity index 100% rename from tests/installer/base.py rename to doctor_tests/installer/base.py diff --git a/tests/installer/common/congress.py b/doctor_tests/installer/common/congress.py similarity index 100% rename from tests/installer/common/congress.py rename to doctor_tests/installer/common/congress.py diff --git a/tests/installer/common/restore_ceilometer.py b/doctor_tests/installer/common/restore_ceilometer.py similarity index 100% rename from tests/installer/common/restore_ceilometer.py rename to doctor_tests/installer/common/restore_ceilometer.py diff --git a/tests/installer/common/set_ceilometer.py b/doctor_tests/installer/common/set_ceilometer.py similarity index 100% rename from tests/installer/common/set_ceilometer.py rename to doctor_tests/installer/common/set_ceilometer.py diff --git a/tests/installer/local.py b/doctor_tests/installer/local.py similarity index 96% rename from tests/installer/local.py rename to doctor_tests/installer/local.py index dcdf41e3..7d0ae542 100644 --- a/tests/installer/local.py +++ b/doctor_tests/installer/local.py @@ -10,9 +10,9 @@ import os import shutil import subprocess -from installer.base import BaseInstaller -from common.utils import load_json_file -from common.utils import write_json_file +from doctor_tests.installer.base import BaseInstaller +from doctor_tests.common.utils import load_json_file +from doctor_tests.common.utils import write_json_file class LocalInstaller(BaseInstaller): diff --git a/tests/instance.py b/doctor_tests/instance.py similarity index 95% rename from tests/instance.py rename to doctor_tests/instance.py index c6acbc3d..27f412e2 100644 --- a/tests/instance.py +++ b/doctor_tests/instance.py @@ -11,10 +11,10 @@ import time from oslo_config import cfg -from identity_auth import get_identity_auth -from identity_auth import get_session -from os_clients import neutron_client -from os_clients import nova_client +from doctor_tests.identity_auth import get_identity_auth +from doctor_tests.identity_auth import get_session +from doctor_tests.os_clients import neutron_client +from doctor_tests.os_clients import nova_client OPTS = [ cfg.StrOpt('flavor', diff --git a/tests/logger.py b/doctor_tests/logger.py similarity index 100% rename from tests/logger.py rename to doctor_tests/logger.py diff --git a/tests/main.py b/doctor_tests/main.py similarity index 87% rename from tests/main.py rename to doctor_tests/main.py index df7e95f3..006aac9f 100644 --- a/tests/main.py +++ b/doctor_tests/main.py @@ -12,25 +12,25 @@ import random import sys import time -from alarm import Alarm -from common.constants import Host -from common.utils import match_rep_in_file -import config -from consumer import get_consumer -from identity_auth import get_identity_auth -from identity_auth import get_session -from image import Image -from instance import Instance -from inspector import get_inspector -from installer import get_installer -import logger as doctor_log -from network import Network -from monitor import get_monitor -from os_clients import nova_client -from profiler_poc import main as profiler_main -from scenario.common import calculate_notification_time -from scenario.network_failure import NetworkFault -from user import User +from doctor_tests.alarm import Alarm +from doctor_tests.common.constants import Host +from doctor_tests.common.utils import match_rep_in_file +from doctor_tests import config +from doctor_tests.consumer import get_consumer +from doctor_tests.identity_auth import get_identity_auth +from doctor_tests.identity_auth import get_session +from doctor_tests.image import Image +from doctor_tests.instance import Instance +from doctor_tests.inspector import get_inspector +from doctor_tests.installer import get_installer +import doctor_tests.logger as doctor_log +from doctor_tests.network import Network +from doctor_tests.monitor import get_monitor +from doctor_tests.os_clients import nova_client +from doctor_tests.profiler_poc import main as profiler_main +from doctor_tests.scenario.common import calculate_notification_time +from doctor_tests.scenario.network_failure import NetworkFault +from doctor_tests.user import User LOG = doctor_log.Logger('doctor').getLogger() @@ -201,7 +201,9 @@ class DoctorTest(object): def main(): """doctor main""" - doctor_root_dir = os.path.dirname(sys.path[0]) + test_dir = os.path.split(os.path.realpath(__file__))[0] + doctor_root_dir = os.path.dirname(test_dir) + config_file_dir = '{0}/{1}'.format(doctor_root_dir, 'etc/') config_files = [join(config_file_dir, f) for f in os.listdir(config_file_dir) if isfile(join(config_file_dir, f))] @@ -211,7 +213,3 @@ def main(): doctor = DoctorTest(conf) doctor.run() - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/tests/monitor/__init__.py b/doctor_tests/monitor/__init__.py similarity index 88% rename from tests/monitor/__init__.py rename to doctor_tests/monitor/__init__.py index e268907f..7e30c9f8 100644 --- a/tests/monitor/__init__.py +++ b/doctor_tests/monitor/__init__.py @@ -19,8 +19,8 @@ OPTS = [ _monitor_name_class_mapping = { - 'sample': 'monitor.sample.SampleMonitor', - 'collectd': 'monitor.collectd.CollectdMonitor' + 'sample': 'doctor_tests.monitor.sample.SampleMonitor', + 'collectd': 'doctor_tests.monitor.collectd.CollectdMonitor' } def get_monitor(conf, inspector_url, log): diff --git a/tests/monitor/base.py b/doctor_tests/monitor/base.py similarity index 100% rename from tests/monitor/base.py rename to doctor_tests/monitor/base.py diff --git a/tests/monitor/collectd.py b/doctor_tests/monitor/collectd.py similarity index 90% rename from tests/monitor/collectd.py rename to doctor_tests/monitor/collectd.py index e2a800ea..4e9329c2 100644 --- a/tests/monitor/collectd.py +++ b/doctor_tests/monitor/collectd.py @@ -6,19 +6,19 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## - import os import socket import getpass import sys -from monitor.base import BaseMonitor +from doctor_tests.monitor.base import BaseMonitor class CollectdMonitor(BaseMonitor): def __init__(self, conf, inspector_url, log): super(CollectdMonitor, self).__init__(conf, inspector_url, log) - self.top_dir = os.path.dirname(sys.path[0]) + monitor_dir = os.path.split(os.path.realpath(__file__))[0] + self.top_dir = os.path.dirname(monitor_dir) tmp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) tmp_sock.connect(("8.8.8.8", 80)) @@ -45,7 +45,7 @@ class CollectdMonitor(BaseMonitor): self.log.info("Collectd monitor start.........") self.compute_host = host.name self.compute_ip = host.ip - f = open("%s/tests/collectd.conf" % self.top_dir, 'w') + f = open("%s/collectd.conf" % self.top_dir, 'w') collectd_conf_file = """ Hostname %s FQDNLookup false @@ -99,7 +99,7 @@ LoadPlugin logfile f.write(collectd_conf_file) f.close() - os.system(" scp %s %s/tests/collectd.conf %s@%s: " % (self.ssh_opts_cpu, self.top_dir, self.compute_user, self.compute_ip)) + os.system(" scp %s %s/collectd.conf %s@%s: " % (self.ssh_opts_cpu, self.top_dir, self.compute_user, self.compute_ip)) self.log.info("after first scp") ## @TODO (umar) Always assuming that the interface is assigned an IP if ## interface name is not provided. See if there is a better approach @@ -117,7 +117,7 @@ LoadPlugin logfile fi sudo mv collectd.conf /opt/collectd/etc/collectd.conf\" """ % (self.ssh_opts_cpu, self.compute_user, self.compute_ip, self.interface_name, self.interface_name, self.compute_ip)) self.log.info("after first ssh") - os.system(" scp %s %s/tests/lib/monitors/collectd/collectd_plugin.py %s@%s:collectd_plugin.py " % (self.ssh_opts_cpu, self.top_dir, self.compute_user, self.compute_ip)) + os.system(" scp %s %s/monitor/collectd_plugin.py %s@%s:collectd_plugin.py " % (self.ssh_opts_cpu, self.top_dir, self.compute_user, self.compute_ip)) self.log.info("after sec scp") os.system(" ssh %s %s@%s \"sudo pkill collectd; sudo /opt/collectd/sbin/collectd\" " % (self.ssh_opts_cpu, self.compute_user, self.compute_ip)) self.log.info("after sec ssh") @@ -135,4 +135,4 @@ LoadPlugin logfile sudo cp -f \"\${collectd_conf}-doctor-saved\" \$collectd_conf sudo rm \"\${collectd_conf}-doctor-saved\" fi\" """ % (self.ssh_opts_cpu, self.compute_user, self.compute_ip)) - os.remove("%s/tests/collectd.conf" % self.top_dir) + os.remove("%s/collectd.conf" % self.top_dir) diff --git a/doctor_tests/monitor/collectd_plugin.py b/doctor_tests/monitor/collectd_plugin.py new file mode 100644 index 00000000..57105f33 --- /dev/null +++ b/doctor_tests/monitor/collectd_plugin.py @@ -0,0 +1,166 @@ +############################################################################## +# Copyright (c) 2017 NEC Corporation 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 +############################################################################## + +import collectd +import sys +from datetime import datetime +import json +import requests +import time +from requests.exceptions import ConnectionError + +from keystoneauth1 import loading +from keystoneauth1 import session +from congressclient.v1 import client + + +def write_debug(str_write, write_type, compute_user): + file_name = ('/home/%s/monitor.log' % compute_user) + file_tmp = open(file_name, write_type) + file_tmp.write( "%s" % str_write) + file_tmp.close() + + +class DoctorMonitorCollectd(object): + def __init__(self): + self.control_ip = '' + self.compute_user = '' + self.compute_ip = '' + self.host_name = '' + self.inspector_type = '' + self.inspector_url = '' + self.os_auth_url = '' + self.os_username = '' + self.os_password = '' + self.os_project_name = '' + self.os_user_domain_name = '' + self.os_user_domain_id = '' + self.os_project_domain_name = '' + self.os_project_domain_id = '' + self.sess = '' + self.auth = '' + self.inspector_notified = 0 + self.start_notifications = 0 + self.monitor_type = 'sample' + + def config_func(self, config): + for node in config.children: + key = node.key.lower() + val = node.values[0] + + if key == 'compute_host': + self.host_name = val + elif key == 'control_ip': + self.control_ip = val + elif key == 'compute_ip': + self.compute_ip = val + elif key == 'compute_user': + self.compute_user = val + elif key == 'inspector_type': + self.inspector_type = val + elif key == 'os_auth_url': + self.os_auth_url = val + elif key == 'os_username': + self.os_username = val + elif key == 'os_password': + self.os_password = val + elif key == 'os_project_name': + self.os_project_name = val + elif key == 'os_user_domain_name': + self.os_user_domain_name = val + elif key == 'os_user_domain_id': + self.os_user_domain_id = val + elif key == 'os_project_domain_name': + self.os_project_domain_name = val + elif key == 'os_project_domain_id': + self.os_project_domain_id = val + else: + collectd.info('Unknown config key "%s"' % key) + + def init_collectd(self): + write_debug("Compute node collectd monitor start at %s\n\n" % datetime.now().isoformat(), "w", self.compute_user) + + if self.inspector_type == 'sample': + self.inspector_url = ('http://%s:12345/events' % self.control_ip) + elif self.inspector_type == 'congress': + loader = loading.get_plugin_loader('password') + self.auth = loader.load_from_options(auth_url=self.os_auth_url, + username=self.os_username, + password=self.os_password, + project_name=self.os_project_name, + user_domain_name=self.os_user_domain_name, + user_domain_id=self.os_user_domain_id, + project_domain_name=self.os_project_domain_name, + project_domain_id=self.os_project_domain_id) + self.sess=session.Session(auth=self.auth) + congress = client.Client(session=self.sess, service_type='policy') + ds = congress.list_datasources()['results'] + doctor_ds = next((item for item in ds if item['driver'] == 'doctor'), + None) + + congress_endpoint = congress.httpclient.get_endpoint(auth=self.auth) + self.inspector_url = ('%s/v1/data-sources/%s/tables/events/rows' % + (congress_endpoint, doctor_ds['id'])) + else: + sys.exit() + self.start_notifications = 1 + + + def notify_inspector(self): + event_type = "compute.host.down" + payload = [ + { + 'id': ("monitor_%s_id1" % self.monitor_type), + 'time': datetime.now().isoformat(), + 'type': event_type, + 'details': { + 'hostname': self.host_name, + 'status': 'down', + 'monitor': ("monitor_%s" % self.monitor_type), + 'monitor_event_id': ("monitor_%s_event1" % self.monitor_type) + }, + }, + ] + data = json.dumps(payload) + self.inspector_notified = 1 + + if self.inspector_type == 'sample': + headers = {'content-type': 'application/json'} + try: + requests.post(self.inspector_url, data=data, headers=headers) + except ConnectionError as err: + print err + elif self.inspector_type == 'congress': + # TODO(umar) enhance for token expiry case + headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'X-Auth-Token': self.sess.get_token() + } + requests.put(self.inspector_url, data=data, headers=headers) + + + def handle_notif(self, notification, data=None): + if (notification.severity == collectd.NOTIF_FAILURE or + notification.severity == collectd.NOTIF_WARNING): + if (self.start_notifications == 1 and self.inspector_notified == 0): + write_debug("Received down notification: doctor monitor detected at %s\n" % time.time(), "a", self.compute_user) + self.notify_inspector() + + elif notification.severity == collectd.NOTIF_OKAY: + collectd.info("Interface status: UP again %s\n" % time.time()) + else: + collectd.info("Unknown notification severity %s\n" % notification.severity) + + +monitor = DoctorMonitorCollectd() + +collectd.register_config(monitor.config_func) +collectd.register_init(monitor.init_collectd) +collectd.register_notification(monitor.handle_notif) diff --git a/tests/monitor/sample.py b/doctor_tests/monitor/sample.py similarity index 97% rename from tests/monitor/sample.py rename to doctor_tests/monitor/sample.py index 9ac1bccf..7a463048 100644 --- a/tests/monitor/sample.py +++ b/doctor_tests/monitor/sample.py @@ -13,8 +13,8 @@ import socket from threading import Thread import time -from identity_auth import get_session -from monitor.base import BaseMonitor +from doctor_tests.identity_auth import get_session +from doctor_tests.monitor.base import BaseMonitor class SampleMonitor(BaseMonitor): diff --git a/tests/network.py b/doctor_tests/network.py similarity index 94% rename from tests/network.py rename to doctor_tests/network.py index da7ad09d..ee153e66 100644 --- a/tests/network.py +++ b/doctor_tests/network.py @@ -8,9 +8,9 @@ ############################################################################## from oslo_config import cfg -from identity_auth import get_identity_auth -from identity_auth import get_session -from os_clients import neutron_client +from doctor_tests.identity_auth import get_identity_auth +from doctor_tests.identity_auth import get_session +from doctor_tests.os_clients import neutron_client OPTS = [ diff --git a/tests/os_clients.py b/doctor_tests/os_clients.py similarity index 100% rename from tests/os_clients.py rename to doctor_tests/os_clients.py diff --git a/tests/profiler_poc.py b/doctor_tests/profiler_poc.py similarity index 100% rename from tests/profiler_poc.py rename to doctor_tests/profiler_poc.py diff --git a/doctor_tests/scenario/__init__.py b/doctor_tests/scenario/__init__.py new file mode 100644 index 00000000..48893ae6 --- /dev/null +++ b/doctor_tests/scenario/__init__.py @@ -0,0 +1,8 @@ +############################################################################## +# Copyright (c) 2017 ZTE Corporation 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 +############################################################################## diff --git a/tests/scenario/common.py b/doctor_tests/scenario/common.py similarity index 90% rename from tests/scenario/common.py rename to doctor_tests/scenario/common.py index a33c50ff..a5cbe483 100644 --- a/tests/scenario/common.py +++ b/doctor_tests/scenario/common.py @@ -7,7 +7,8 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## import sys -from common.utils import match_rep_in_file + +from doctor_tests.common.utils import match_rep_in_file def calculate_notification_time(): @@ -25,4 +26,4 @@ def calculate_notification_time(): raise Exception('Can not match notified time') notified = result.group(0) - return float(notified) - float(detected) \ No newline at end of file + return float(notified) - float(detected) diff --git a/tests/scenario/network_failure.py b/doctor_tests/scenario/network_failure.py similarity index 94% rename from tests/scenario/network_failure.py rename to doctor_tests/scenario/network_failure.py index e9a239db..b94a622d 100644 --- a/tests/scenario/network_failure.py +++ b/doctor_tests/scenario/network_failure.py @@ -6,9 +6,9 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## -from identity_auth import get_session -from os_clients import nova_client -from common.utils import SSHClient +from doctor_tests.identity_auth import get_session +from doctor_tests.os_clients import nova_client +from doctor_tests.common.utils import SSHClient LINK_DOWN_SCRIPT = """ #!/bin/bash -x diff --git a/tests/user.py b/doctor_tests/user.py similarity index 97% rename from tests/user.py rename to doctor_tests/user.py index b21bd1a8..33f995e7 100644 --- a/tests/user.py +++ b/doctor_tests/user.py @@ -10,9 +10,9 @@ import os from oslo_config import cfg -from identity_auth import get_session -from os_clients import keystone_client -from os_clients import nova_client +from doctor_tests.identity_auth import get_session +from doctor_tests.os_clients import keystone_client +from doctor_tests.os_clients import nova_client OPTS = [ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..4623289d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,14 @@ +Flask!=0.11,<1.0,>=0.10 # BSD +paramiko>=2.0 # LGPLv2.1+ +scp +requests!=2.12.2,>=2.10.0 # Apache-2.0 +oslo.config!=3.18.0,>=3.14.0 # Apache-2.0 +python-openstackclient>=3.3.0 # Apache-2.0 +python-ceilometerclient>=2.5.0 # Apache-2.0 +aodhclient>=0.7.0 # Apache-2.0 +python-keystoneclient>=3.8.0 # Apache-2.0 +python-neutronclient>=5.1.0 # Apache-2.0 +python-novaclient!=7.0.0,>=6.0.0 # Apache-2.0 +python-congressclient<2000,>=1.3.0 # Apache-2.0 +python-glanceclient>=2.5.0 # Apache-2.0 +virtualenv>=13.1.0 # MIT diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..a9e8144c --- /dev/null +++ b/setup.cfg @@ -0,0 +1,11 @@ +[metadata] +name = doctor-tests +version = 2017.9.0 +home-page = https://wiki.opnfv.org/display/doctor/Doctor+Home + +[files] +packages = doctor_tests + +[entry_points] +console_scripts = + doctor-test = doctor_tests.main:main diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..a1e9b3bb --- /dev/null +++ b/setup.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +# Copyright (c) 2017 Orange 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 + +import setuptools + +# In python < 2.7.4, a lazy loading of package `pbr` will break +# setuptools if some other modules registered functions in `atexit`. +# solution from: http://bugs.python.org/issue15881#msg170215 +try: + import multiprocessing # noqa +except ImportError: + pass + +setuptools.setup( + setup_requires=['pbr>=1.8'], + pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index 070caa44..00000000 --- a/test-requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -Flask==0.10.1 -paramiko==1.16.0 -scp==0.10.2 -requests>=2.8.0 -oslo.config==3.22.0 # Apache-2.0 -python-openstackclient==2.3.0 -python-ceilometerclient==2.6.2 -aodhclient==0.7.0 -python-keystoneclient==3.5.0 -python-neutronclient==6.0.0 -python-novaclient==6.0.0 -python-congressclient==1.5.0 -python-glanceclient==2.5.0 -virtualenv==15.1.0 diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/inspector.py b/tests/inspector.py index 82ffc338..0046b999 100644 --- a/tests/inspector.py +++ b/tests/inspector.py @@ -19,7 +19,7 @@ import time from keystoneauth1 import session import novaclient.client as novaclient -import identity_auth +import doctor_tests.identity_auth LOG = doctor_log.Logger('doctor_inspector').getLogger() diff --git a/tests/run.sh b/tests/run.sh index e1875e09..b5c56872 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -42,6 +42,8 @@ ceilometer="ceilometer $as_doctor_user" as_admin_user="--os-username admin --os-project-name $DOCTOR_PROJECT --os-tenant-name $DOCTOR_PROJECT" +upper_constraints="https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/ocata" +pip_install="pip install -c${upper_constraints}" # Functions @@ -477,16 +479,16 @@ cleanup() { } setup_python_packages() { - sudo pip install flask==0.10.1 - command -v openstack || sudo pip install python-openstackclient==2.3.0 - command -v ceilometer || sudo pip install python-ceilometerclient==2.6.2 - command -v congress || sudo pip install python-congressclient==1.5.0 + pip freeze |grep -i flask\= > /dev/null || sudo ${pip_install} flask + command -v openstack || sudo ${pip_install} python-openstackclient + command -v ceilometer || sudo ${pip_install} python-ceilometerclient + command -v congress || sudo ${pip_install} python-congressclient } # Main process if [[ $PYTHON_ENABLE == [Tt]rue ]]; then - which tox || sudo pip install tox + which tox || sudo ${pip_install} tox if [ -f /usr/bin/apt-get ]; then sudo apt-get install -y python3-dev elif [ -f /usr/bin/yum ] ; then diff --git a/tox.ini b/tox.ini index d4babeb8..748241e7 100644 --- a/tox.ini +++ b/tox.ini @@ -4,9 +4,12 @@ envlist = py34 skipsdist = True [testenv] -install_command = pip install -U {opts} {packages} +usedevelop = True +install_command = pip install \ + -chttps://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/ocata \ + {opts} {packages} setenv = VIRTUAL_ENV={envdir} -deps = -r{toxinidir}/test-requirements.txt +deps = -r{toxinidir}/requirements.txt passenv = OS_AUTH_URL OS_USERNAME @@ -23,6 +26,5 @@ passenv = INSTALLER_TYPE INSTALLER_IP PROFILER_TYPE -changedir = {toxinidir}/tests -commands = python main.py - +changedir = {toxinidir}/doctor_tests +commands = doctor-test