Compare commits

...

3 Commits
3.0.0 ... 3.0.1

Author SHA1 Message Date
Zuul
e37bbf3be3 Merge "Don't throw exception when missing metrics" into stable/train 2019-10-21 02:07:33 +00:00
licanwei
8e143ca8bf Remove print()
Change-Id: Ida31237b77e98c803cb1ccb3bd5b190289434207
(cherry picked from commit aa36e6a881)
2019-10-18 06:28:45 +00:00
licanwei
e5884a963b Don't throw exception when missing metrics
When querying data from datasource, it's possible to miss some data.
In this case if we throw an exception, Audit will failed because of
the exception. We should remove the exception and give the decision
to the strategy.

Change-Id: I1b0e6b78b3bba4df9ba16e093b3910aab1de922e
Closes-Bug: #1847434
(cherry picked from commit f685bf62ab)
2019-10-18 02:54:10 +00:00
8 changed files with 27 additions and 39 deletions

View File

@@ -19,8 +19,6 @@ import time
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log from oslo_log import log
from watcher.common import exception
CONF = cfg.CONF CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
@@ -79,7 +77,6 @@ class DataSourceBase(object):
LOG.warning("Retry {0} of {1} while retrieving metrics retry " LOG.warning("Retry {0} of {1} while retrieving metrics retry "
"in {2} seconds".format(i+1, num_retries, timeout)) "in {2} seconds".format(i+1, num_retries, timeout))
time.sleep(timeout) time.sleep(timeout)
raise exception.DataSourceNotAvailable(datasource=self.NAME)
@abc.abstractmethod @abc.abstractmethod
def query_retry_reset(self, exception_instance): def query_retry_reset(self, exception_instance):

View File

@@ -136,19 +136,18 @@ class CeilometerHelper(base.DataSourceBase):
def list_metrics(self): def list_metrics(self):
"""List the user's meters.""" """List the user's meters."""
try: meters = self.query_retry(f=self.ceilometer.meters.list)
meters = self.query_retry(f=self.ceilometer.meters.list) if not meters:
except Exception:
return set() return set()
else: else:
return meters return meters
def check_availability(self): def check_availability(self):
try: status = self.query_retry(self.ceilometer.resources.list)
self.query_retry(self.ceilometer.resources.list) if status:
except Exception: return 'available'
else:
return 'not available' return 'not available'
return 'available'
def query_sample(self, meter_name, query, limit=1): def query_sample(self, meter_name, query, limit=1):
return self.query_retry(f=self.ceilometer.samples.list, return self.query_retry(f=self.ceilometer.samples.list,

View File

@@ -52,17 +52,16 @@ class GnocchiHelper(base.DataSourceBase):
self.gnocchi = self.osc.gnocchi() self.gnocchi = self.osc.gnocchi()
def check_availability(self): def check_availability(self):
try: status = self.query_retry(self.gnocchi.status.get)
self.query_retry(self.gnocchi.status.get) if status:
except Exception: return 'available'
else:
return 'not available' return 'not available'
return 'available'
def list_metrics(self): def list_metrics(self):
"""List the user's meters.""" """List the user's meters."""
try: response = self.query_retry(f=self.gnocchi.metric.list)
response = self.query_retry(f=self.gnocchi.metric.list) if not response:
except Exception:
return set() return set()
else: else:
return set([metric['name'] for metric in response]) return set([metric['name'] for metric in response])
@@ -91,8 +90,9 @@ class GnocchiHelper(base.DataSourceBase):
f=self.gnocchi.resource.search, **kwargs) f=self.gnocchi.resource.search, **kwargs)
if not resources: if not resources:
raise exception.ResourceNotFound(name='gnocchi', LOG.warning("The {0} resource {1} could not be "
id=resource_id) "found".format(self.NAME, resource_id))
return
resource_id = resources[0]['id'] resource_id = resources[0]['id']
@@ -110,6 +110,7 @@ class GnocchiHelper(base.DataSourceBase):
statistics = self.query_retry( statistics = self.query_retry(
f=self.gnocchi.metric.get_measures, **kwargs) f=self.gnocchi.metric.get_measures, **kwargs)
return_value = None
if statistics: if statistics:
# return value of latest measure # return value of latest measure
# measure has structure [time, granularity, value] # measure has structure [time, granularity, value]
@@ -120,7 +121,7 @@ class GnocchiHelper(base.DataSourceBase):
# 1/10 th of actual CFM # 1/10 th of actual CFM
return_value *= 10 return_value *= 10
return return_value return return_value
def get_host_cpu_usage(self, resource, period, aggregate, def get_host_cpu_usage(self, resource, period, aggregate,
granularity=300): granularity=300):

View File

@@ -179,6 +179,9 @@ class GrafanaHelper(base.DataSourceBase):
kwargs = {k: v for k, v in raw_kwargs.items() if k and v} kwargs = {k: v for k, v in raw_kwargs.items() if k and v}
resp = self.query_retry(self._request, **kwargs) resp = self.query_retry(self._request, **kwargs)
if not resp:
LOG.warning("Datasource {0} is not available.".format(self.NAME))
return
result = translator.extract_result(resp.content) result = translator.extract_result(resp.content)

View File

@@ -73,11 +73,11 @@ class MonascaHelper(base.DataSourceBase):
self.monasca = self.osc.monasca() self.monasca = self.osc.monasca()
def check_availability(self): def check_availability(self):
try: result = self.query_retry(self.monasca.metrics.list)
self.query_retry(self.monasca.metrics.list) if result:
except Exception: return 'available'
else:
return 'not available' return 'not available'
return 'available'
def list_metrics(self): def list_metrics(self):
# TODO(alexchadin): this method should be implemented in accordance to # TODO(alexchadin): this method should be implemented in accordance to

View File

@@ -105,7 +105,6 @@ class FunctionalTest(base.DbTestCase):
:param path_prefix: prefix of the url path :param path_prefix: prefix of the url path
""" """
full_path = path_prefix + path full_path = path_prefix + path
print('%s: %s %s' % (method.upper(), full_path, params))
response = getattr(self.app, "%s_json" % method)( response = getattr(self.app, "%s_json" % method)(
str(full_path), str(full_path),
@@ -115,7 +114,6 @@ class FunctionalTest(base.DbTestCase):
extra_environ=extra_environ, extra_environ=extra_environ,
expect_errors=expect_errors expect_errors=expect_errors
) )
print('GOT:%s' % response)
return response return response
def put_json(self, path, params, expect_errors=False, headers=None, def put_json(self, path, params, expect_errors=False, headers=None,
@@ -192,13 +190,11 @@ class FunctionalTest(base.DbTestCase):
:param path_prefix: prefix of the url path :param path_prefix: prefix of the url path
""" """
full_path = path_prefix + path full_path = path_prefix + path
print('DELETE: %s' % (full_path))
response = self.app.delete(str(full_path), response = self.app.delete(str(full_path),
headers=headers, headers=headers,
status=status, status=status,
extra_environ=extra_environ, extra_environ=extra_environ,
expect_errors=expect_errors) expect_errors=expect_errors)
print('GOT:%s' % response)
return response return response
def get_json(self, path, expect_errors=False, headers=None, def get_json(self, path, expect_errors=False, headers=None,
@@ -229,7 +225,6 @@ class FunctionalTest(base.DbTestCase):
all_params.update(params) all_params.update(params)
if q: if q:
all_params.update(query_params) all_params.update(query_params)
print('GET: %s %r' % (full_path, all_params))
response = self.app.get(full_path, response = self.app.get(full_path,
params=all_params, params=all_params,
@@ -238,7 +233,6 @@ class FunctionalTest(base.DbTestCase):
expect_errors=expect_errors) expect_errors=expect_errors)
if return_json and not expect_errors: if return_json and not expect_errors:
response = response.json response = response.json
print('GOT:%s' % response)
return response return response
def validate_link(self, link, bookmark=False): def validate_link(self, link, bookmark=False):

View File

@@ -19,7 +19,6 @@
import mock import mock
from oslo_config import cfg from oslo_config import cfg
from watcher.common import exception
from watcher.decision_engine.datasources import base as datasource from watcher.decision_engine.datasources import base as datasource
from watcher.tests import base from watcher.tests import base
@@ -61,9 +60,8 @@ class TestBaseDatasourceHelper(base.BaseTestCase):
helper = datasource.DataSourceBase() helper = datasource.DataSourceBase()
helper.query_retry_reset = mock.Mock() helper.query_retry_reset = mock.Mock()
# Maximum number of retries exceeded query_retry should raise error # Maximum number of retries exceeded query_retry should return None
self.assertRaises(exception.DataSourceNotAvailable, self.assertIsNone(helper.query_retry(f=method))
helper.query_retry, f=method)
# query_retry_reset should be called twice # query_retry_reset should be called twice
helper.query_retry_reset.assert_has_calls( helper.query_retry_reset.assert_has_calls(
[mock.call(exc), mock.call(exc)]) [mock.call(exc), mock.call(exc)])

View File

@@ -132,11 +132,7 @@ class TestGrafana(base.BaseTestCase):
t_grafana = grafana.GrafanaHelper(osc=mock.Mock()) t_grafana = grafana.GrafanaHelper(osc=mock.Mock())
self.assertRaises( self.assertIsNone(t_grafana.get_host_cpu_usage(self.m_compute_node))
exception.DataSourceNotAvailable,
t_grafana.get_host_cpu_usage,
self.m_compute_node
)
def test_no_metric_raise_error(self): def test_no_metric_raise_error(self):
"""Test raising error when specified meter does not exist""" """Test raising error when specified meter does not exist"""