Versioned Notifications for service object
Implements: blueprint service-versioned-notifications-api Change-Id: I9d601edb265ee230104f6c63a5f044869aeb3a02
This commit is contained in:
@@ -32,6 +32,7 @@ from six.moves.urllib import parse as urlparse
|
||||
|
||||
from watcher.api import hooks
|
||||
from watcher.common import context as watcher_context
|
||||
from watcher.notifications import service as n_service
|
||||
from watcher.tests.db import base
|
||||
|
||||
PATH_PREFIX = '/v1'
|
||||
@@ -55,6 +56,12 @@ class FunctionalTest(base.DbTestCase):
|
||||
cfg.CONF.set_override("admin_user", "admin",
|
||||
group='keystone_authtoken',
|
||||
enforce_type=True)
|
||||
|
||||
p_services = mock.patch.object(n_service, "send_service_update",
|
||||
new_callable=mock.PropertyMock)
|
||||
self.m_services = p_services.start()
|
||||
self.addCleanup(p_services.stop)
|
||||
|
||||
self.app = self._make_app()
|
||||
|
||||
def reset_pecan():
|
||||
|
||||
114
watcher/tests/api/test_scheduling.py
Normal file
114
watcher/tests/api/test_scheduling.py
Normal file
@@ -0,0 +1,114 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from apscheduler.schedulers import background
|
||||
import datetime
|
||||
import freezegun
|
||||
import mock
|
||||
|
||||
from watcher.api import scheduling
|
||||
from watcher.notifications import service
|
||||
from watcher import objects
|
||||
from watcher.tests import base
|
||||
from watcher.tests.db import base as db_base
|
||||
from watcher.tests.db import utils
|
||||
|
||||
|
||||
class TestSchedulingService(base.TestCase):
|
||||
|
||||
@mock.patch.object(background.BackgroundScheduler, 'start')
|
||||
def test_start_scheduling_service(self, m_start):
|
||||
scheduler = scheduling.APISchedulingService()
|
||||
scheduler.start()
|
||||
m_start.assert_called_once_with(scheduler)
|
||||
jobs = scheduler.get_jobs()
|
||||
self.assertEqual(1, len(jobs))
|
||||
|
||||
|
||||
class TestSchedulingServiceFunctions(db_base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSchedulingServiceFunctions, self).setUp()
|
||||
fake_service = utils.get_test_service(
|
||||
created_at=datetime.datetime.utcnow())
|
||||
self.fake_service = objects.Service(**fake_service)
|
||||
|
||||
@mock.patch.object(scheduling.APISchedulingService, 'get_service_status')
|
||||
@mock.patch.object(objects.Service, 'list')
|
||||
@mock.patch.object(service, 'send_service_update')
|
||||
def test_get_services_status_without_services_in_list(
|
||||
self, mock_service_update, mock_get_list, mock_service_status):
|
||||
scheduler = scheduling.APISchedulingService()
|
||||
mock_get_list.return_value = [self.fake_service]
|
||||
mock_service_status.return_value = 'ACTIVE'
|
||||
scheduler.get_services_status(mock.ANY)
|
||||
mock_service_status.assert_called_once_with(mock.ANY,
|
||||
self.fake_service.id)
|
||||
|
||||
mock_service_update.assert_not_called()
|
||||
|
||||
@mock.patch.object(scheduling.APISchedulingService, 'get_service_status')
|
||||
@mock.patch.object(objects.Service, 'list')
|
||||
@mock.patch.object(service, 'send_service_update')
|
||||
def test_get_services_status_with_services_in_list_same_status(
|
||||
self, mock_service_update, mock_get_list, mock_service_status):
|
||||
scheduler = scheduling.APISchedulingService()
|
||||
mock_get_list.return_value = [self.fake_service]
|
||||
scheduler.services_status = {1: 'ACTIVE'}
|
||||
mock_service_status.return_value = 'ACTIVE'
|
||||
scheduler.get_services_status(mock.ANY)
|
||||
mock_service_status.assert_called_once_with(mock.ANY,
|
||||
self.fake_service.id)
|
||||
|
||||
mock_service_update.assert_not_called()
|
||||
|
||||
@mock.patch.object(scheduling.APISchedulingService, 'get_service_status')
|
||||
@mock.patch.object(objects.Service, 'list')
|
||||
@mock.patch.object(service, 'send_service_update')
|
||||
def test_get_services_status_with_services_in_list_diff_status(
|
||||
self, mock_service_update, mock_get_list, mock_service_status):
|
||||
scheduler = scheduling.APISchedulingService()
|
||||
mock_get_list.return_value = [self.fake_service]
|
||||
scheduler.services_status = {1: 'FAILED'}
|
||||
mock_service_status.return_value = 'ACTIVE'
|
||||
scheduler.get_services_status(mock.ANY)
|
||||
mock_service_status.assert_called_once_with(mock.ANY,
|
||||
self.fake_service.id)
|
||||
|
||||
mock_service_update.assert_called_once_with(mock.ANY,
|
||||
self.fake_service,
|
||||
state='ACTIVE')
|
||||
|
||||
@mock.patch.object(objects.Service, 'get')
|
||||
def test_get_service_status_failed_service(
|
||||
self, mock_get):
|
||||
scheduler = scheduling.APISchedulingService()
|
||||
mock_get.return_value = self.fake_service
|
||||
service_status = scheduler.get_service_status(mock.ANY,
|
||||
self.fake_service.id)
|
||||
mock_get.assert_called_once_with(mock.ANY,
|
||||
self.fake_service.id)
|
||||
self.assertEqual('FAILED', service_status)
|
||||
|
||||
@freezegun.freeze_time('2016-09-22T08:32:26.219414')
|
||||
@mock.patch.object(objects.Service, 'get')
|
||||
def test_get_service_status_failed_active(
|
||||
self, mock_get):
|
||||
scheduler = scheduling.APISchedulingService()
|
||||
mock_get.return_value = self.fake_service
|
||||
service_status = scheduler.get_service_status(mock.ANY,
|
||||
self.fake_service.id)
|
||||
mock_get.assert_called_once_with(mock.ANY,
|
||||
self.fake_service.id)
|
||||
self.assertEqual('ACTIVE', service_status)
|
||||
@@ -288,6 +288,11 @@ expected_notification_fingerprints = {
|
||||
'ActionUpdateNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
'ActionUpdatePayload': '1.0-03306c7e7f4d49ac328c261eff6b30b8',
|
||||
'TerseActionPlanPayload': '1.0-42bf7a5585cc111a9a4dbc008a04c67e',
|
||||
'ServiceUpdateNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
'ServicePayload': '1.0-9c5a9bc51e6606e0ec3cf95baf698f4f',
|
||||
'ServiceStatusUpdatePayload': '1.0-1a1b606bf14a2c468800c2b010801ce5',
|
||||
'ServiceUpdatePayload': '1.0-e0e9812a45958974693a723a2c820c3f'
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
77
watcher/tests/notifications/test_service_notifications.py
Normal file
77
watcher/tests/notifications/test_service_notifications.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2017 Servionica
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import datetime
|
||||
|
||||
import freezegun
|
||||
import mock
|
||||
import oslo_messaging as om
|
||||
|
||||
from watcher.common import rpc
|
||||
from watcher import notifications
|
||||
from watcher.objects import service as w_service
|
||||
from watcher.tests.db import base
|
||||
from watcher.tests.objects import utils
|
||||
|
||||
|
||||
@freezegun.freeze_time('2016-10-18T09:52:05.219414')
|
||||
class TestActionPlanNotification(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestActionPlanNotification, self).setUp()
|
||||
p_get_notifier = mock.patch.object(rpc, 'get_notifier')
|
||||
m_get_notifier = p_get_notifier.start()
|
||||
self.addCleanup(p_get_notifier.stop)
|
||||
self.m_notifier = mock.Mock(spec=om.Notifier)
|
||||
|
||||
def fake_get_notifier(publisher_id):
|
||||
self.m_notifier.publisher_id = publisher_id
|
||||
return self.m_notifier
|
||||
|
||||
m_get_notifier.side_effect = fake_get_notifier
|
||||
|
||||
def test_service_failed(self):
|
||||
service = utils.get_test_service(mock.Mock(),
|
||||
created_at=datetime.datetime.utcnow())
|
||||
state = w_service.ServiceStatus.FAILED
|
||||
notifications.service.send_service_update(mock.MagicMock(),
|
||||
service,
|
||||
state,
|
||||
host='node0')
|
||||
notification = self.m_notifier.warning.call_args[1]
|
||||
payload = notification['payload']
|
||||
self.assertEqual("infra-optim:node0", self.m_notifier.publisher_id)
|
||||
self.assertDictEqual({
|
||||
'watcher_object.data': {
|
||||
'last_seen_up': '2016-09-22T08:32:06Z',
|
||||
'name': 'watcher-service',
|
||||
'sevice_host': 'controller',
|
||||
'status_update': {
|
||||
'watcher_object.data': {
|
||||
'old_state': 'ACTIVE',
|
||||
'state': 'FAILED'
|
||||
},
|
||||
'watcher_object.name': 'ServiceStatusUpdatePayload',
|
||||
'watcher_object.namespace': 'watcher',
|
||||
'watcher_object.version': '1.0'
|
||||
}
|
||||
},
|
||||
'watcher_object.name': 'ServiceUpdatePayload',
|
||||
'watcher_object.namespace': 'watcher',
|
||||
'watcher_object.version': '1.0'
|
||||
},
|
||||
payload
|
||||
)
|
||||
Reference in New Issue
Block a user