diff --git a/aodh/evaluator/__init__.py b/aodh/evaluator/__init__.py index 1ccbe827..6ba2b190 100644 --- a/aodh/evaluator/__init__.py +++ b/aodh/evaluator/__init__.py @@ -34,6 +34,7 @@ import uuid import aodh from aodh import coordination from aodh.i18n import _ +from aodh import keystone_client from aodh import messaging from aodh import rpc from aodh import storage @@ -65,6 +66,13 @@ class Evaluator(object): self.conf = conf self.notifier = notifier self.storage_conn = None + self._ks_client = None + + @property + def ks_client(self): + if self._ks_client is None: + self._ks_client = keystone_client.get_client(self.conf) + return self._ks_client @property def _storage_conn(self): @@ -77,10 +85,7 @@ class Evaluator(object): return type = models.AlarmChange.STATE_TRANSITION detail = json.dumps({'state': alarm.state}) - # TODO(liusheng) the user_id and project_id should be - # specify than None? - user_id = None - project_id = None + user_id, project_id = self.ks_client.user_id, self.ks_client.project_id on_behalf_of = alarm.project_id now = timeutils.utcnow() payload = dict(event_id=str(uuid.uuid4()), diff --git a/aodh/evaluator/gnocchi.py b/aodh/evaluator/gnocchi.py index 90a67cb3..021f8dcd 100644 --- a/aodh/evaluator/gnocchi.py +++ b/aodh/evaluator/gnocchi.py @@ -20,7 +20,6 @@ import requests from aodh.evaluator import threshold from aodh.i18n import _ -from aodh import keystone_client LOG = log.getLogger(__name__) @@ -39,13 +38,6 @@ class GnocchiThresholdEvaluator(threshold.ThresholdEvaluator): def __init__(self, conf, notifier): super(threshold.ThresholdEvaluator, self).__init__(conf, notifier) self.gnocchi_url = cfg.CONF.gnocchi_url - self._ks_client = None - - @property - def ks_client(self): - if self._ks_client is None: - self._ks_client = keystone_client.get_client(cfg.CONF) - return self._ks_client def _get_headers(self, content_type="application/json"): return { diff --git a/aodh/tests/evaluator/base.py b/aodh/tests/evaluator/base.py index 96a1dc30..d596b496 100644 --- a/aodh/tests/evaluator/base.py +++ b/aodh/tests/evaluator/base.py @@ -26,6 +26,9 @@ class TestEvaluatorBase(base.BaseTestCase): self.evaluator = self.EVALUATOR(self.conf, self.notifier) self.storage_conn = mock.MagicMock() self.evaluator.storage_conn = self.storage_conn + self.evaluator._ks_client = mock.Mock(user_id='fake_user_id', + project_id='fake_project_id', + auth_token='fake_token') self.prepare_alarms() @staticmethod diff --git a/aodh/tests/evaluator/test_gnocchi.py b/aodh/tests/evaluator/test_gnocchi.py index 1584eee6..bd7d9883 100644 --- a/aodh/tests/evaluator/test_gnocchi.py +++ b/aodh/tests/evaluator/test_gnocchi.py @@ -45,12 +45,6 @@ class TestGnocchiThresholdEvaluate(base.TestEvaluatorBase): EVALUATOR = gnocchi.GnocchiThresholdEvaluator def setUp(self): - ks_client = mock.Mock(auth_token='fake_token') - ks_client.users.find.return_value = 'gnocchi' - self.useFixture(mockpatch.Patch( - 'keystoneclient.v2_0.client.Client', - return_value=ks_client)) - super(TestGnocchiThresholdEvaluate, self).setUp() self.useFixture(mockpatch.Patch('ceilometerclient.client.get_client', diff --git a/aodh/tests/evaluator/test_threshold.py b/aodh/tests/evaluator/test_threshold.py index 1a460b6d..7843e7a2 100644 --- a/aodh/tests/evaluator/test_threshold.py +++ b/aodh/tests/evaluator/test_threshold.py @@ -15,6 +15,7 @@ """Tests for aodh/evaluator/threshold.py """ import datetime +import json import uuid from ceilometerclient import exc @@ -25,6 +26,7 @@ import pytz from six import moves from aodh.evaluator import threshold +from aodh import messaging from aodh.storage import models from aodh.tests import constants from aodh.tests.evaluator import base @@ -223,6 +225,59 @@ class TestEvaluate(base.TestEvaluatorBase): in zip(self.alarms, reasons, reason_datas)] self.assertEqual(expected, self.notifier.notify.call_args_list) + def _construct_payloads(self): + payloads = [] + for alarm in self.alarms: + type = models.AlarmChange.STATE_TRANSITION + detail = json.dumps({'state': alarm.state}) + on_behalf_of = alarm.project_id + payload = dict( + event_id='fake_event_id_%s' % self.alarms.index(alarm), + alarm_id=alarm.alarm_id, + type=type, + detail=detail, + user_id='fake_user_id', + project_id='fake_project_id', + on_behalf_of=on_behalf_of, + timestamp=datetime.datetime(2015, 7, 26, 3, 33, 21, 876795)) + payloads.append(payload) + return payloads + + @mock.patch.object(uuid, 'uuid4') + @mock.patch.object(timeutils, 'utcnow') + @mock.patch.object(messaging, 'get_notifier') + def test_alarm_change_record(self, get_notifier, utcnow, mock_uuid): + # the context.RequestContext() method need to generate uuid, + # so we need to provide 'fake_uuid_0' and 'fake_uuid_1' for that. + mock_uuid.side_effect = ['fake_event_id_0', 'fake_uuid_0', + 'fake_event_id_1', 'fake_uuid_1'] + change_notifier = mock.MagicMock() + get_notifier.return_value = change_notifier + utcnow.return_value = datetime.datetime(2015, 7, 26, 3, 33, 21, 876795) + self._set_all_alarms('ok') + with mock.patch('ceilometerclient.client.get_client', + return_value=self.api_client): + avgs = [self._get_stat('avg', self.alarms[0].rule['threshold'] + v) + for v in moves.xrange(1, 6)] + maxs = [self._get_stat('max', self.alarms[1].rule['threshold'] - v) + for v in moves.xrange(4)] + self.api_client.statistics.list.side_effect = [avgs, maxs] + self._evaluate_all_alarms() + self._assert_all_alarms('alarm') + expected = [mock.call(alarm) for alarm in self.alarms] + update_calls = self.storage_conn.update_alarm.call_args_list + self.assertEqual(expected, update_calls) + payloads = self._construct_payloads() + expected_payloads = [mock.call(p) for p in payloads] + change_records = \ + self.storage_conn.record_alarm_change.call_args_list + self.assertEqual(expected_payloads, change_records) + notify_calls = change_notifier.info.call_args_list + notification = "alarm.state_transition" + expected_payloads = [mock.call(mock.ANY, notification, p) + for p in payloads] + self.assertEqual(expected_payloads, notify_calls) + def test_equivocal_from_known_state(self): self._set_all_alarms('ok') with mock.patch('ceilometerclient.client.get_client',