aodh/ceilometer/tests/ipmi/pollsters/test_sensor.py
Chris Dent 8323cfe92a Handle poorly formed individual sensor readings
ipmitool returns a series of multiple readings per run. Some of
these readings may be of a form that parser code cannot handle. The
desired behavior in this case is for the single reading to be
dropped and for parsing to continue. This change ensures that
behavior by continuing through the loop instead of allowing
exceptions to cause the loop to exit.

Tests have been added which verify the correct behavior.

Note that though there was an opportunity to log each skipped
reading this would lead to a very large number of log messages as
many or even most samples from ipmitool are not parsed.

Change-Id: I6a3193d5a6e12c69ca5c548e5fb58d8bc9646348
Closes-Bug: #1381600
2014-10-15 17:22:41 +01:00

177 lines
4.6 KiB
Python

# Copyright 2014 Intel Corp.
#
# Author: Zhai Edwin <edwin.zhai@intel.com>
#
# 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 mock
from oslo.config import cfg
from ceilometer.ipmi.pollsters import sensor
from ceilometer.tests.ipmi.notifications import ipmi_test_data
from ceilometer.tests.ipmi.pollsters import base
CONF = cfg.CONF
CONF.import_opt('host', 'ceilometer.service')
TEMPERATURE_SENSOR_DATA = {
'Temperature': ipmi_test_data.TEMPERATURE_DATA
}
CURRENT_SENSOR_DATA = {
'Current': ipmi_test_data.CURRENT_DATA
}
FAN_SENSOR_DATA = {
'Fan': ipmi_test_data.FAN_DATA
}
VOLTAGE_SENSOR_DATA = {
'Voltage': ipmi_test_data.VOLTAGE_DATA
}
MISSING_SENSOR_DATA = ipmi_test_data.MISSING_SENSOR['payload']['payload']
MALFORMED_SENSOR_DATA = ipmi_test_data.BAD_SENSOR['payload']['payload']
MISSING_ID_SENSOR_DATA = ipmi_test_data.NO_SENSOR_ID['payload']['payload']
class TestTemperatureSensorPollster(base.TestPollsterBase):
def fake_sensor_data(self, sensor_type):
return TEMPERATURE_SENSOR_DATA
def fake_data(self):
# No use for Sensor test
return None
def make_pollster(self):
return sensor.TemperatureSensorPollster()
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
def test_get_samples(self):
self._test_get_samples()
self._verify_metering(10, float(32), CONF.host)
class TestMissingSensorData(base.TestPollsterBase):
def fake_sensor_data(self, sensor_type):
return MISSING_SENSOR_DATA
def fake_data(self):
# No use for Sensor test
return None
def make_pollster(self):
return sensor.TemperatureSensorPollster()
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
def test_get_samples(self):
self._test_get_samples()
self._verify_metering(0)
class TestMalformedSensorData(base.TestPollsterBase):
def fake_sensor_data(self, sensor_type):
return MALFORMED_SENSOR_DATA
def fake_data(self):
# No use for Sensor test
return None
def make_pollster(self):
return sensor.TemperatureSensorPollster()
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
def test_get_samples(self):
self._test_get_samples()
self._verify_metering(0)
class TestMissingSensorId(base.TestPollsterBase):
def fake_sensor_data(self, sensor_type):
return MISSING_ID_SENSOR_DATA
def fake_data(self):
# No use for Sensor test
return None
def make_pollster(self):
return sensor.TemperatureSensorPollster()
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
def test_get_samples(self):
self._test_get_samples()
self._verify_metering(0)
class TestFanSensorPollster(base.TestPollsterBase):
def fake_sensor_data(self, sensor_type):
return FAN_SENSOR_DATA
def fake_data(self):
# No use for Sensor test
return None
def make_pollster(self):
return sensor.FanSensorPollster()
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
def test_get_samples(self):
self._test_get_samples()
self._verify_metering(12, float(7140), CONF.host)
class TestCurrentSensorPollster(base.TestPollsterBase):
def fake_sensor_data(self, sensor_type):
return CURRENT_SENSOR_DATA
def fake_data(self):
# No use for Sensor test
return None
def make_pollster(self):
return sensor.CurrentSensorPollster()
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
def test_get_samples(self):
self._test_get_samples()
self._verify_metering(1, float(130), CONF.host)
class TestVoltageSensorPollster(base.TestPollsterBase):
def fake_sensor_data(self, sensor_type):
return VOLTAGE_SENSOR_DATA
def fake_data(self):
# No use for Sensor test
return None
def make_pollster(self):
return sensor.VoltageSensorPollster()
@mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock())
def test_get_samples(self):
self._test_get_samples()
self._verify_metering(4, float(3.309), CONF.host)