Merge "Add is_up property to service and cluster objects"
This commit is contained in:
commit
4c978d2e8f
@ -50,7 +50,7 @@ class ViewBuilder(object):
|
||||
result = {
|
||||
'name': cluster.name,
|
||||
'binary': cluster.binary,
|
||||
'state': 'up' if cluster.is_up() else 'down',
|
||||
'state': 'up' if cluster.is_up else 'down',
|
||||
'status': 'disabled' if cluster.disabled else 'enabled',
|
||||
}
|
||||
if flat:
|
||||
|
@ -151,8 +151,7 @@ class API(base.Base):
|
||||
ctxt, topic, disabled=False)
|
||||
for srv in services:
|
||||
if (self._az_matched(srv, availability_zone) and
|
||||
srv.host == host and
|
||||
utils.service_is_up(srv)):
|
||||
srv.host == host and srv.is_up):
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -169,7 +168,7 @@ class API(base.Base):
|
||||
while idx < len(services):
|
||||
srv = services[idx]
|
||||
if(self._az_matched(srv, availability_zone) and
|
||||
utils.service_is_up(srv)):
|
||||
srv.is_up):
|
||||
return srv.host
|
||||
idx = idx + 1
|
||||
return None
|
||||
@ -199,7 +198,7 @@ class API(base.Base):
|
||||
def _list_backup_hosts(self):
|
||||
services = self._list_backup_services()
|
||||
return [srv.host for srv in services
|
||||
if not srv.disabled and utils.service_is_up(srv)]
|
||||
if not srv.disabled and srv.is_up]
|
||||
|
||||
def create(self, context, name, description, volume_id,
|
||||
container, incremental=False, availability_zone=None,
|
||||
|
@ -81,7 +81,6 @@ from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import objects
|
||||
from cinder import rpc
|
||||
from cinder import utils
|
||||
from cinder import version
|
||||
from cinder.volume import utils as vutils
|
||||
|
||||
@ -519,7 +518,7 @@ class ServiceCommands(BaseCommand):
|
||||
_('Object Version'),
|
||||
_('Cluster')))
|
||||
for svc in services:
|
||||
art = self._state_repr(utils.service_is_up(svc))
|
||||
art = self._state_repr(svc.is_up)
|
||||
status = 'disabled' if svc.disabled else 'enabled'
|
||||
updated_at = self._normalize_time(svc.updated_at)
|
||||
rpc_version = svc.rpc_current_version
|
||||
@ -566,7 +565,7 @@ class ClusterCommands(BaseCommand):
|
||||
_('Down Hosts'),
|
||||
_('Updated At')))
|
||||
for cluster in clusters:
|
||||
art = self._state_repr(cluster.is_up())
|
||||
art = self._state_repr(cluster.is_up)
|
||||
status = 'disabled' if cluster.disabled else 'enabled'
|
||||
heartbeat = self._normalize_time(cluster.last_heartbeat)
|
||||
updated_at = self._normalize_time(cluster.updated_at)
|
||||
|
@ -146,6 +146,7 @@ class Cluster(base.CinderPersistentObject, base.CinderObject,
|
||||
setattr(self, field, value)
|
||||
self.obj_reset_changes(updated_values.keys())
|
||||
|
||||
@property
|
||||
def is_up(self):
|
||||
return (self.last_heartbeat and
|
||||
self.last_heartbeat >= utils.service_expired_time(True))
|
||||
|
@ -21,6 +21,7 @@ from cinder.i18n import _
|
||||
from cinder import objects
|
||||
from cinder.objects import base
|
||||
from cinder.objects import fields as c_fields
|
||||
from cinder import utils
|
||||
|
||||
|
||||
@base.CinderObjectRegistry.register
|
||||
@ -190,6 +191,13 @@ class Service(base.CinderPersistentObject, base.CinderObject,
|
||||
return cls._get_minimum_version('object_current_version', context,
|
||||
binary)
|
||||
|
||||
@property
|
||||
def is_up(self):
|
||||
"""Check whether a service is up based on last heartbeat."""
|
||||
last_heartbeat = self.updated_at or self.created_at
|
||||
return (last_heartbeat and
|
||||
last_heartbeat >= utils.service_expired_time(True))
|
||||
|
||||
|
||||
@base.CinderObjectRegistry.register
|
||||
class ServiceList(base.ObjectListBase, base.CinderObject):
|
||||
|
@ -28,7 +28,6 @@ from cinder.common import constants
|
||||
from cinder import context as cinder_context
|
||||
from cinder import exception
|
||||
from cinder import objects
|
||||
from cinder import utils
|
||||
from cinder.i18n import _LI, _LW
|
||||
from cinder.scheduler import filters
|
||||
from cinder.volume import utils as vol_utils
|
||||
@ -465,7 +464,7 @@ class HostManager(object):
|
||||
no_capabilities_hosts = set()
|
||||
for service in volume_services.objects:
|
||||
host = service.host
|
||||
if not utils.service_is_up(service):
|
||||
if not service.is_up:
|
||||
LOG.warning(_LW("volume service is down. (host: %s)"), host)
|
||||
continue
|
||||
capabilities = self.service_states.get(host, None)
|
||||
|
@ -144,7 +144,9 @@ class SnapshotManageTest(test.TestCase):
|
||||
args = mock_rpcapi.call_args[0]
|
||||
self.assertEqual('fake_ref', args[2])
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=True)
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
return_value=True,
|
||||
new_callable=mock.PropertyMock)
|
||||
@mock.patch('cinder.volume.rpcapi.VolumeAPI.manage_existing_snapshot')
|
||||
@mock.patch('cinder.volume.api.API.create_snapshot_in_db')
|
||||
@mock.patch('cinder.db.service_get')
|
||||
@ -162,7 +164,8 @@ class SnapshotManageTest(test.TestCase):
|
||||
mock_rpcapi.assert_not_called()
|
||||
mock_is_up.assert_not_called()
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=False)
|
||||
@mock.patch('cinder.objects.service.Service.is_up', return_value=False,
|
||||
new_callable=mock.PropertyMock)
|
||||
@mock.patch('cinder.volume.rpcapi.VolumeAPI.manage_existing_snapshot')
|
||||
@mock.patch('cinder.volume.api.API.create_snapshot_in_db')
|
||||
@mock.patch('cinder.db.service_get')
|
||||
@ -276,7 +279,7 @@ class SnapshotManageTest(test.TestCase):
|
||||
self._admin_ctxt, 'fakehost', limit=10, marker='1234', offset=4,
|
||||
sort_dirs=['asc'], sort_keys=['reference'])
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=True)
|
||||
@mock.patch('cinder.objects.service.Service.is_up', return_value=True)
|
||||
@mock.patch('cinder.db.service_get')
|
||||
def test_get_manageable_snapshots_disabled(self, mock_db, mock_is_up):
|
||||
mock_db.return_value = fake_service.fake_service_obj(self._admin_ctxt,
|
||||
@ -287,7 +290,8 @@ class SnapshotManageTest(test.TestCase):
|
||||
res.json['badRequest']['message'])
|
||||
mock_is_up.assert_not_called()
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=False)
|
||||
@mock.patch('cinder.objects.service.Service.is_up', return_value=False,
|
||||
new_callable=mock.PropertyMock)
|
||||
@mock.patch('cinder.db.service_get')
|
||||
def test_get_manageable_snapshots_is_down(self, mock_db, mock_is_up):
|
||||
mock_db.return_value = fake_service.fake_service_obj(self._admin_ctxt)
|
||||
|
@ -250,7 +250,8 @@ class VolumeManageTest(test.TestCase):
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=True)
|
||||
@mock.patch('cinder.objects.service.Service.is_up', return_value=True,
|
||||
new_callable=mock.PropertyMock)
|
||||
def test_manage_volume_disabled(self, mock_is_up):
|
||||
"""Test manage volume failure due to disabled service."""
|
||||
body = {'volume': {'host': 'host_disabled', 'ref': 'fake_ref'}}
|
||||
@ -260,7 +261,8 @@ class VolumeManageTest(test.TestCase):
|
||||
res.json['badRequest']['message'])
|
||||
mock_is_up.assert_not_called()
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=False)
|
||||
@mock.patch('cinder.objects.service.Service.is_up', return_value=False,
|
||||
new_callable=mock.PropertyMock)
|
||||
def test_manage_volume_is_down(self, mock_is_up):
|
||||
"""Test manage volume failure due to down service."""
|
||||
body = {'volume': {'host': 'host_ok', 'ref': 'fake_ref'}}
|
||||
@ -396,7 +398,8 @@ class VolumeManageTest(test.TestCase):
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(400, res.status_int)
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=True)
|
||||
@mock.patch('cinder.objects.service.Service.is_up', return_value=True,
|
||||
new_callable=mock.PropertyMock)
|
||||
def test_get_manageable_volumes_disabled(self, mock_is_up):
|
||||
res = self._get_resp_get('host_disabled', False, True)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
@ -404,7 +407,8 @@ class VolumeManageTest(test.TestCase):
|
||||
res.json['badRequest']['message'])
|
||||
mock_is_up.assert_not_called()
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up', return_value=False)
|
||||
@mock.patch('cinder.objects.service.Service.is_up', return_value=False,
|
||||
new_callable=mock.PropertyMock)
|
||||
def test_get_manageable_volumes_is_down(self, mock_is_up):
|
||||
res = self._get_resp_get('host_ok', False, True)
|
||||
self.assertEqual(400, res.status_int, res)
|
||||
|
@ -88,27 +88,27 @@ class TestCluster(test_objects.BaseObjectsTestCase):
|
||||
def test_is_up_no_last_hearbeat(self):
|
||||
cluster = fake_cluster.fake_cluster_ovo(self.context,
|
||||
last_heartbeat=None)
|
||||
self.assertFalse(cluster.is_up())
|
||||
self.assertFalse(cluster.is_up)
|
||||
|
||||
def test_is_up(self):
|
||||
cluster = fake_cluster.fake_cluster_ovo(
|
||||
self.context,
|
||||
last_heartbeat=timeutils.utcnow(with_timezone=True))
|
||||
self.assertTrue(cluster.is_up())
|
||||
self.assertTrue(cluster.is_up)
|
||||
|
||||
def test_is_up_limit(self):
|
||||
limit_expired = (utils.service_expired_time(True) +
|
||||
timeutils.datetime.timedelta(seconds=1))
|
||||
cluster = fake_cluster.fake_cluster_ovo(self.context,
|
||||
last_heartbeat=limit_expired)
|
||||
self.assertTrue(cluster.is_up())
|
||||
self.assertTrue(cluster.is_up)
|
||||
|
||||
def test_is_up_down(self):
|
||||
expired_time = (utils.service_expired_time(True) -
|
||||
timeutils.datetime.timedelta(seconds=1))
|
||||
cluster = fake_cluster.fake_cluster_ovo(self.context,
|
||||
last_heartbeat=expired_time)
|
||||
self.assertFalse(cluster.is_up())
|
||||
self.assertFalse(cluster.is_up)
|
||||
|
||||
|
||||
class TestClusterList(test_objects.BaseObjectsTestCase):
|
||||
|
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import datetime
|
||||
import mock
|
||||
from oslo_utils import timeutils
|
||||
import pytz
|
||||
@ -177,6 +178,28 @@ class TestService(test_objects.BaseObjectsTestCase):
|
||||
cluster_get.assert_called_once_with(self.context, None,
|
||||
name='mycluster')
|
||||
|
||||
def test_service_is_up(self):
|
||||
# NOTE(mdovgal): don't use @ddt.data with the real timestamp value
|
||||
# for this test.
|
||||
# When using ddt decorators ddt.data seems to have been calculated
|
||||
# not at the time of test's execution but at the tests's beginning.
|
||||
# And this one depends on utcnow func. So it won't be utcnow at the
|
||||
# execution moment and the result will be unexpected.
|
||||
down_time = 5
|
||||
self.flags(service_down_time=down_time)
|
||||
|
||||
# test if service is up
|
||||
service = fake_service.fake_service_obj(self.context)
|
||||
self.assertTrue(service.is_up)
|
||||
|
||||
service.updated_at = timeutils.utcnow()
|
||||
self.assertTrue(service.is_up)
|
||||
|
||||
# test is service is down now
|
||||
past_time = timeutils.utcnow() - datetime.timedelta(seconds=64)
|
||||
service.updated_at = past_time
|
||||
self.assertFalse(service.is_up)
|
||||
|
||||
|
||||
class TestServiceList(test_objects.BaseObjectsTestCase):
|
||||
@mock.patch('cinder.db.service_get_all')
|
||||
|
@ -48,6 +48,8 @@ class HostFiltersTestCase(test.TestCase):
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
new_callable=mock.PropertyMock)
|
||||
class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
def setUp(self):
|
||||
super(CapacityFilterTestCase, self).setUp()
|
||||
@ -56,7 +58,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
['>=', '$free_capacity_gb', 1024],
|
||||
['>=', '$total_capacity_gb', 10 * 1024]])
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_passes(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -69,7 +70,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_current_host_passes(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -82,7 +82,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_fails(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -96,7 +95,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_fails_free_capacity_None(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -108,7 +106,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_passes_infinite(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -120,7 +117,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_passes_unknown(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -132,7 +128,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_passes_total_infinite(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -146,7 +141,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_passes_total_unknown(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -160,7 +154,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_fails_total_infinite(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -173,7 +166,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_fails_total_unknown(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -186,7 +178,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_fails_total_zero(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -199,7 +190,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_thin_true_passes(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -221,7 +211,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_thin_true_passes2(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -243,7 +232,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_thin_false_passes(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -267,7 +255,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_over_subscription_less_than_1(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -289,7 +276,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_over_subscription_equal_to_1(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -311,7 +297,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_over_subscription_fails(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -333,7 +318,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_over_subscription_fails2(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -355,7 +339,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_reserved_thin_true_fails(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -377,7 +360,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_reserved_thin_false_fails(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -401,7 +383,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_reserved_thin_thick_true_fails(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -423,7 +404,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_reserved_thin_thick_true_passes(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -445,7 +425,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_reserved_thin_true_passes(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -467,7 +446,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_reserved_thin_thick_true_fails2(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -489,7 +467,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_reserved_thin_thick_true_passes2(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -519,7 +496,6 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
{'volume_type': None},
|
||||
)
|
||||
@ddt.unpack
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
def test_filter_provisioning_type(self, _mock_serv_is_up, volume_type):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['CapacityFilter']()
|
||||
@ -540,7 +516,8 @@ class CapacityFilterTestCase(HostFiltersTestCase):
|
||||
|
||||
|
||||
class AffinityFilterTestCase(HostFiltersTestCase):
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
new_callable=mock.PropertyMock)
|
||||
def test_different_filter_passes(self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
filt_cls = self.class_map['DifferentBackendFilter']()
|
||||
@ -558,7 +535,8 @@ class AffinityFilterTestCase(HostFiltersTestCase):
|
||||
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
new_callable=mock.PropertyMock)
|
||||
def test_different_filter_legacy_volume_hint_passes(
|
||||
self, _mock_serv_is_up):
|
||||
_mock_serv_is_up.return_value = True
|
||||
|
@ -117,7 +117,8 @@ class HostManagerTestCase(test.TestCase):
|
||||
'host3': host3_volume_capabs}
|
||||
self.assertDictMatch(expected, service_states)
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
new_callable=mock.PropertyMock)
|
||||
@mock.patch('cinder.db.service_get_all')
|
||||
def test_has_all_capabilities(self, _mock_service_get_all,
|
||||
_mock_service_is_up):
|
||||
@ -151,7 +152,8 @@ class HostManagerTestCase(test.TestCase):
|
||||
self.assertTrue(self.host_manager.has_all_capabilities())
|
||||
|
||||
@mock.patch('cinder.db.service_get_all')
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
new_callable=mock.PropertyMock)
|
||||
@mock.patch('oslo_utils.timeutils.utcnow')
|
||||
def test_update_and_get_pools(self, _mock_utcnow,
|
||||
_mock_service_is_up,
|
||||
@ -204,7 +206,8 @@ class HostManagerTestCase(test.TestCase):
|
||||
self.assertEqual(dates[2], res[0]['capabilities']['timestamp'])
|
||||
|
||||
@mock.patch('cinder.db.service_get_all')
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
new_callable=mock.PropertyMock)
|
||||
def test_get_all_host_states(self, _mock_service_is_up,
|
||||
_mock_service_get_all):
|
||||
context = 'fake_context'
|
||||
@ -250,8 +253,7 @@ class HostManagerTestCase(test.TestCase):
|
||||
timestamp=None, reserved_percentage=0,
|
||||
provisioned_capacity_gb=9300),
|
||||
}
|
||||
|
||||
# First test: service_is_up is always True, host5 is disabled,
|
||||
# First test: service.is_up is always True, host5 is disabled,
|
||||
# host4 has no capabilities
|
||||
self.host_manager.service_states = service_states
|
||||
_mock_service_get_all.return_value = services
|
||||
@ -264,9 +266,9 @@ class HostManagerTestCase(test.TestCase):
|
||||
_mock_service_get_all.assert_called_with(context,
|
||||
disabled=False,
|
||||
topic=topic)
|
||||
expected = []
|
||||
for service in service_objs:
|
||||
expected.append(mock.call(service))
|
||||
|
||||
# verify that Service.is_up was called for each srv
|
||||
expected = [mock.call() for s in service_objs]
|
||||
self.assertEqual(expected, _mock_service_is_up.call_args_list)
|
||||
|
||||
# Get host_state_map and make sure we have the first 3 hosts
|
||||
@ -278,7 +280,7 @@ class HostManagerTestCase(test.TestCase):
|
||||
test_service.TestService._compare(self, volume_node,
|
||||
host_state_map[host].service)
|
||||
|
||||
# Second test: Now service_is_up returns False for host3
|
||||
# Second test: Now service.is_up returns False for host3
|
||||
_mock_service_is_up.reset_mock()
|
||||
_mock_service_is_up.side_effect = [True, True, False, True]
|
||||
_mock_service_get_all.reset_mock()
|
||||
@ -304,7 +306,8 @@ class HostManagerTestCase(test.TestCase):
|
||||
host_state_map[host].service)
|
||||
|
||||
@mock.patch('cinder.db.service_get_all')
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
new_callable=mock.PropertyMock)
|
||||
def test_get_pools(self, _mock_service_is_up,
|
||||
_mock_service_get_all):
|
||||
context = 'fake_context'
|
||||
|
@ -615,7 +615,8 @@ class TestCinderManageCmd(test.TestCase):
|
||||
consisgroup_update.assert_called_once_with(
|
||||
ctxt, fake.CONSISTENCY_GROUP_ID, {'host': 'fake_host2'})
|
||||
|
||||
@mock.patch('cinder.utils.service_is_up')
|
||||
@mock.patch('cinder.objects.service.Service.is_up',
|
||||
new_callable=mock.PropertyMock)
|
||||
@mock.patch('cinder.db.service_get_all')
|
||||
@mock.patch('cinder.context.get_admin_context')
|
||||
def _test_service_commands_list(self, service, get_admin_context,
|
||||
|
@ -214,33 +214,6 @@ class GenericUtilsTestCase(test.TestCase):
|
||||
mock_isfile.assert_called_once_with(tempfile)
|
||||
mock_unlink.assert_called_once_with(tempfile)
|
||||
|
||||
@mock.patch('oslo_utils.timeutils.utcnow')
|
||||
def test_service_is_up(self, mock_utcnow):
|
||||
fts_func = datetime.datetime.fromtimestamp
|
||||
fake_now = 1000
|
||||
down_time = 5
|
||||
|
||||
self.flags(service_down_time=down_time)
|
||||
mock_utcnow.return_value = fts_func(fake_now)
|
||||
|
||||
# Up (equal)
|
||||
service = {'updated_at': fts_func(fake_now - down_time),
|
||||
'created_at': fts_func(fake_now - down_time)}
|
||||
result = utils.service_is_up(service)
|
||||
self.assertTrue(result)
|
||||
|
||||
# Up
|
||||
service = {'updated_at': fts_func(fake_now - down_time + 1),
|
||||
'created_at': fts_func(fake_now - down_time + 1)}
|
||||
result = utils.service_is_up(service)
|
||||
self.assertTrue(result)
|
||||
|
||||
# Down
|
||||
service = {'updated_at': fts_func(fake_now - down_time - 1),
|
||||
'created_at': fts_func(fake_now - down_time - 1)}
|
||||
result = utils.service_is_up(service)
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_check_ssh_injection(self):
|
||||
cmd_list = ['ssh', '-D', 'my_name@name_of_remote_computer']
|
||||
self.assertIsNone(utils.check_ssh_injection(cmd_list))
|
||||
|
@ -361,15 +361,6 @@ def sanitize_hostname(hostname):
|
||||
return hostname
|
||||
|
||||
|
||||
def service_is_up(service):
|
||||
"""Check whether a service is up based on last heartbeat."""
|
||||
last_heartbeat = service['updated_at'] or service['created_at']
|
||||
# Timestamps in DB are UTC.
|
||||
elapsed = (timeutils.utcnow(with_timezone=True) -
|
||||
last_heartbeat).total_seconds()
|
||||
return abs(elapsed) <= CONF.service_down_time
|
||||
|
||||
|
||||
def read_file_as_root(file_path):
|
||||
"""Secure helper to read file as root."""
|
||||
try:
|
||||
|
@ -1334,7 +1334,7 @@ class API(base.Base):
|
||||
found = False
|
||||
svc_host = volume_utils.extract_host(host, 'backend')
|
||||
for service in services:
|
||||
if utils.service_is_up(service) and service.host == svc_host:
|
||||
if service.is_up and service.host == svc_host:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
@ -1552,7 +1552,7 @@ class API(base.Base):
|
||||
'service.'), resource)
|
||||
raise exception.ServiceUnavailable()
|
||||
|
||||
if not utils.service_is_up(service):
|
||||
if not service.is_up:
|
||||
LOG.error(_LE('Unable to manage existing %s on a service that is '
|
||||
'down.'), resource)
|
||||
raise exception.ServiceUnavailable()
|
||||
|
Loading…
x
Reference in New Issue
Block a user