コード例 #1
0
    def test_create_volume_fails_with_creating_and_downloading_status(
            self, mock_cleanup_tmp_file):
        """Test init_host_with_service in case of volume.

        While the status of volume is 'creating' or 'downloading',
        volume process down.
        After process restarting this 'creating' status is changed to 'error'.
        """
        for status in ('creating', 'downloading'):
            volume = tests_utils.create_volume(self.context,
                                               status=status,
                                               size=0,
                                               host=CONF.host)

            db.worker_create(self.context,
                             resource_type='Volume',
                             resource_id=volume.id,
                             status=volume.status,
                             service_id=self.service_id)

            self.volume.init_host(service_id=service.Service.service_id)
            volume.refresh()

            self.assertEqual('error', volume['status'])
            self.volume.delete_volume(self.context, volume)
            self.assertTrue(mock_cleanup_tmp_file.called)
            self._assert_workers_are_removed()
コード例 #2
0
ファイル: cleanable.py プロジェクト: NetApp/cinder
    def create_worker(self, pinned=True):
        """Create a worker entry at the API."""
        # This method is mostly called from the rpc layer, therefore it checks
        # if it's cleanable given current pinned version.
        if not self.is_cleanable(pinned):
            return False

        resource_type = self.__class__.__name__

        entry_in_db = False

        # This will only loop on very rare race conditions
        while not entry_in_db:
            try:
                # On the common case there won't be an entry in the DB, that's
                # why we try to create first.
                db.worker_create(self._context, status=self.status,
                                 resource_type=resource_type,
                                 resource_id=self.id)
                entry_in_db = True
            except exception.WorkerExists:
                try:
                    db.worker_update(self._context, None,
                                     filters={'resource_type': resource_type,
                                              'resource_id': self.id},
                                     service_id=None,
                                     status=self.status)
                    entry_in_db = True
                except exception.WorkerNotFound:
                    pass
        return entry_in_db
コード例 #3
0
    def create_worker(self, pinned=True):
        """Create a worker entry at the API."""
        # This method is mostly called from the rpc layer, therefore it checks
        # if it's cleanable given current pinned version.
        if not self.is_cleanable(pinned):
            return False

        resource_type = self.__class__.__name__

        entry_in_db = False

        # This will only loop on very rare race conditions
        while not entry_in_db:
            try:
                # On the common case there won't be an entry in the DB, that's
                # why we try to create first.
                db.worker_create(self._context,
                                 status=self.status,
                                 resource_type=resource_type,
                                 resource_id=self.id)
                entry_in_db = True
            except exception.WorkerExists:
                try:
                    db.worker_update(self._context,
                                     None,
                                     filters={
                                         'resource_type': resource_type,
                                         'resource_id': self.id
                                     },
                                     service_id=None,
                                     status=self.status)
                    entry_in_db = True
                except exception.WorkerNotFound:
                    pass
        return entry_in_db
コード例 #4
0
    def test_do_cleanup_not_cleaning_already_claimed(self):
        """Basic cleanup that doesn't touch already cleaning works."""
        vol = utils.create_volume(self.context, status='creating')
        worker1 = db.worker_create(self.context, status='creating',
                                   resource_type='Volume', resource_id=vol.id,
                                   service_id=self.service.id)
        worker1 = db.worker_get(self.context, id=worker1.id)
        vol2 = utils.create_volume(self.context, status='deleting')
        worker2 = db.worker_create(self.context, status='deleting',
                                   resource_type='Volume', resource_id=vol2.id,
                                   service_id=self.service.id + 1)
        worker2 = db.worker_get(self.context, id=worker2.id)

        # Simulate that the change to vol2 worker happened between
        # worker_get_all and trying to claim a work for cleanup
        worker2.service_id = self.service.id

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        with mock.patch('cinder.db.worker_get_all') as get_all_mock:
            get_all_mock.return_value = [worker1, worker2]
            mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))
        self.assertEqual(worker2.id, workers[0].id)

        vol.refresh()
        self.assertEqual('creating_cleaned', vol.status)
        vol2.refresh()
        self.assertEqual('deleting', vol2.status)
コード例 #5
0
    def test_create_snapshot_fails_with_creating_status(self):
        """Test init_host_with_service in case of snapshot.

        While the status of snapshot is 'creating', volume process
        down. After process restarting this 'creating' status is
        changed to 'error'.
        """
        volume = tests_utils.create_volume(self.context, **self.volume_params)
        snapshot = tests_utils.create_snapshot(
            self.context, volume.id, status=fields.SnapshotStatus.CREATING)
        db.worker_create(self.context,
                         resource_type='Snapshot',
                         resource_id=snapshot.id,
                         status=snapshot.status,
                         service_id=self.service_id)

        self.volume.init_host(service_id=service.Service.service_id)

        snapshot_obj = objects.Snapshot.get_by_id(self.context, snapshot.id)

        self.assertEqual(fields.SnapshotStatus.ERROR, snapshot_obj.status)
        self.assertEqual(service.Service.service_id, self.volume.service_id)
        self._assert_workers_are_removed()

        self.volume.delete_snapshot(self.context, snapshot_obj)
        self.volume.delete_volume(self.context, volume)
コード例 #6
0
    def test_create_snapshot_fails_with_creating_status(self):
        """Test init_host_with_service in case of snapshot.

        While the status of snapshot is 'creating', volume process
        down. After process restarting this 'creating' status is
        changed to 'error'.
        """
        volume = tests_utils.create_volume(self.context,
                                           **self.volume_params)
        snapshot = tests_utils.create_snapshot(
            self.context,
            volume.id,
            status=fields.SnapshotStatus.CREATING)
        db.worker_create(self.context, resource_type='Snapshot',
                         resource_id=snapshot.id, status=snapshot.status,
                         service_id=self.service_id)

        self.volume.init_host(service_id=service.Service.service_id)

        snapshot_obj = objects.Snapshot.get_by_id(self.context, snapshot.id)

        self.assertEqual(fields.SnapshotStatus.ERROR, snapshot_obj.status)
        self.assertEqual(service.Service.service_id,
                         self.volume.service_id)
        self._assert_workers_are_removed()

        self.volume.delete_snapshot(self.context, snapshot_obj)
        self.volume.delete_volume(self.context, volume)
コード例 #7
0
    def test_do_cleanup_not_cleaning_already_claimed(self):
        """Basic cleanup that doesn't touch already cleaning works."""
        vol = utils.create_volume(self.context, status='creating')
        worker1 = db.worker_create(self.context,
                                   status='creating',
                                   resource_type='Volume',
                                   resource_id=vol.id,
                                   service_id=self.service.id)
        worker1 = db.worker_get(self.context, id=worker1.id)
        vol2 = utils.create_volume(self.context, status='deleting')
        worker2 = db.worker_create(self.context,
                                   status='deleting',
                                   resource_type='Volume',
                                   resource_id=vol2.id,
                                   service_id=self.service.id + 1)
        worker2 = db.worker_get(self.context, id=worker2.id)

        # Simulate that the change to vol2 worker happened between
        # worker_get_all and trying to claim a work for cleanup
        worker2.service_id = self.service.id

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        with mock.patch('cinder.db.worker_get_all') as get_all_mock:
            get_all_mock.return_value = [worker1, worker2]
            mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))
        self.assertEqual(worker2.id, workers[0].id)

        vol.refresh()
        self.assertEqual('creating_cleaned', vol.status)
        vol2.refresh()
        self.assertEqual('deleting', vol2.status)
コード例 #8
0
 def test_worker_create_unique_constrains(self):
     """Test when we use an already existing resource type and id."""
     db.worker_create(self.ctxt, **self.worker_fields)
     self.assertRaises(exception.WorkerExists, db.worker_create,
                       self.ctxt,
                       resource_type=self.worker_fields['resource_type'],
                       resource_id=self.worker_fields['resource_id'],
                       status='not_' + self.worker_fields['status'])
コード例 #9
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
 def test_worker_get_non_existent(self):
     """Check basic non existent worker record get method."""
     db.worker_create(self.ctxt, **self.worker_fields)
     self.assertRaises(exception.WorkerNotFound,
                       db.worker_get,
                       self.ctxt,
                       service_id='1',
                       **self.worker_fields)
コード例 #10
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
 def test_worker_create_unique_constrains(self):
     """Test when we use an already existing resource type and id."""
     db.worker_create(self.ctxt, **self.worker_fields)
     self.assertRaises(exception.WorkerExists,
                       db.worker_create,
                       self.ctxt,
                       resource_type=self.worker_fields['resource_type'],
                       resource_id=self.worker_fields['resource_id'],
                       status='not_' + self.worker_fields['status'])
コード例 #11
0
    def test_init_host_clears_uploads_available_volume(self):
        """init_host will clean an available volume stuck in uploading."""
        volume = tests_utils.create_volume(self.context, status='uploading',
                                           size=0, host=CONF.host)

        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)

        self.volume.init_host(service_id=service.Service.service_id)
        volume.refresh()
        self.assertEqual("available", volume.status)
        self._assert_workers_are_removed()
コード例 #12
0
    def test_init_host_clears_uploads_available_volume(self):
        """init_host will clean an available volume stuck in uploading."""
        volume = tests_utils.create_volume(self.context, status='uploading',
                                           size=0, host=CONF.host)

        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)

        self.volume.init_host(service_id=service.Service.service_id)
        volume.refresh()
        self.assertEqual("available", volume.status)
        self._assert_workers_are_removed()
コード例 #13
0
    def test_do_cleanup(self):
        """Basic successful cleanup."""
        vol = utils.create_volume(self.context, status='creating')
        db.worker_create(self.context, status='creating',
                         resource_type='Volume', resource_id=vol.id,
                         service_id=self.service.id)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        self.assertListEqual([], db.worker_get_all(self.context))
        vol.refresh()
        self.assertEqual('creating_cleaned', vol.status)
コード例 #14
0
    def test_init_host_clears_deleting_snapshots(self):
        """Test that init_host will delete a snapshot stuck in deleting."""
        volume = tests_utils.create_volume(self.context, status='deleting',
                                           size=1, host=CONF.host)
        snapshot = tests_utils.create_snapshot(self.context,
                                               volume.id, status='deleting')

        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)

        self.volume.init_host(service_id=self.service_id)
        self.assertRaises(exception.VolumeNotFound, volume.refresh)
        self.assertRaises(exception.SnapshotNotFound, snapshot.refresh)
コード例 #15
0
    def test_do_cleanup_resource_deleted(self):
        """Cleanup on a resource that's been already deleted."""
        vol = utils.create_volume(self.context, status='creating')
        db.worker_create(self.context, status='creating',
                         resource_type='Volume', resource_id=vol.id,
                         service_id=self.service.id)
        vol.destroy()

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertListEqual([], workers)
コード例 #16
0
    def test_init_host_resumes_deletes(self):
        """init_host will resume deleting volume in deleting status."""
        volume = tests_utils.create_volume(self.context, status='deleting',
                                           size=0, host=CONF.host)

        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)

        self.volume.init_host(service_id=service.Service.service_id)

        self.assertRaises(exception.VolumeNotFound, db.volume_get,
                          context.get_admin_context(), volume.id)
        self._assert_workers_are_removed()
コード例 #17
0
    def test_init_host_clears_deleting_snapshots(self):
        """Test that init_host will delete a snapshot stuck in deleting."""
        volume = tests_utils.create_volume(self.context, status='deleting',
                                           size=1, host=CONF.host)
        snapshot = tests_utils.create_snapshot(self.context,
                                               volume.id, status='deleting')

        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)

        self.volume.init_host(service_id=self.service_id)
        self.assertRaises(exception.VolumeNotFound, volume.refresh)
        self.assertRaises(exception.SnapshotNotFound, snapshot.refresh)
コード例 #18
0
    def test_do_cleanup_revive_on_cleanup_fail(self, mock_clean):
        """Cleanup will revive a worker if cleanup fails."""
        vol = utils.create_volume(self.context, status='creating')
        db.worker_create(self.context, status='creating',
                         resource_type='Volume', resource_id=vol.id,
                         service_id=self.service.id)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))
        vol.refresh()
        self.assertEqual('creating', vol.status)
コード例 #19
0
    def test_do_cleanup_keep_worker(self):
        """Cleanup on a resource that will remove worker when cleaning up."""
        vol = utils.create_volume(self.context, status='deleting')
        db.worker_create(self.context, status='deleting',
                         resource_type='Volume', resource_id=vol.id,
                         service_id=self.service.id)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id, keep_after_clean=True)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))
        vol.refresh()
        self.assertEqual('deleting_cleaned', vol.status)
コード例 #20
0
    def test_init_host_resumes_deletes(self, mock_cleanup_tmp_file):
        """init_host will resume deleting volume in deleting status."""
        volume = tests_utils.create_volume(self.context, status='deleting',
                                           size=0, host=CONF.host)

        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)

        self.volume.init_host(service_id=service.Service.service_id)

        self.assertRaises(exception.VolumeNotFound, db.volume_get,
                          context.get_admin_context(), volume.id)
        mock_cleanup_tmp_file.assert_called_once_with(CONF.host)
        self._assert_workers_are_removed()
コード例 #21
0
    def test_do_cleanup_resource_changed_status(self):
        """Cleanup on a resource that's changed status."""
        vol = utils.create_volume(self.context, status='available')
        db.worker_create(self.context, status='creating',
                         resource_type='Volume', resource_id=vol.id,
                         service_id=self.service.id)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertListEqual([], workers)

        vol.refresh()
        self.assertEqual('available', vol.status)
コード例 #22
0
    def test_do_cleanup_resource_on_another_service(self):
        """Cleanup on a resource that's been claimed by other service."""
        vol = utils.create_volume(self.context, status='deleting')
        db.worker_create(self.context, status='deleting',
                         resource_type='Volume', resource_id=vol.id,
                         service_id=self.service.id + 1)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))

        vol.refresh()
        self.assertEqual('deleting', vol.status)
コード例 #23
0
    def test_do_cleanup_resource_deleted(self):
        """Cleanup on a resource that's been already deleted."""
        vol = utils.create_volume(self.context, status='creating')
        db.worker_create(self.context,
                         status='creating',
                         resource_type='Volume',
                         resource_id=vol.id,
                         service_id=self.service.id)
        vol.destroy()

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertListEqual([], workers)
コード例 #24
0
 def test_worker_create_no_subsecond(self, mock_utcnow):
     """Test basic creation of a worker record."""
     db.sqlalchemy.api.DB_SUPPORTS_SUBSECOND_RESOLUTION = False
     worker = db.worker_create(self.ctxt, **self.worker_fields)
     db_worker = db.worker_get(self.ctxt, id=worker.id)
     self._assertEqualObjects(worker, db_worker)
     self.assertEqual(0, db_worker.updated_at.microsecond)
コード例 #25
0
    def test_worker_claim_fails_this_service_claimed(self):
        """Test claim fails when worker was already claimed by this service."""
        service_id = 1
        worker = db.worker_create(self.ctxt, resource_type='Volume',
                                  resource_id=fake.VOLUME_ID,
                                  status='creating',
                                  service_id=service_id)

        # Read it back to have the updated_at value
        worker = db.worker_get(self.ctxt, id=worker.id)
        claimed_worker = db.worker_get(self.ctxt, id=worker.id)

        time.sleep(0.1)
        # Simulate that this service starts processing this entry
        res = db.worker_claim_for_cleanup(self.ctxt,
                                          service_id,
                                          claimed_worker)
        self.assertEqual(1, res)

        res = db.worker_claim_for_cleanup(self.ctxt, service_id, worker)
        self.assertEqual(0, res)
        db_worker = db.worker_get(self.ctxt, id=worker.id)
        self._assertEqualObjects(claimed_worker, db_worker)
        self._assertEqualObjects(worker, db_worker,
                                 ['updated_at', 'race_preventer'])
        self.assertNotEqual(worker.updated_at, db_worker.updated_at)
        self.assertEqual(worker.race_preventer + 1, db_worker.race_preventer)
コード例 #26
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
    def test_worker_claim_fails_this_service_claimed(self):
        """Test claim fails when worker was already claimed by this service."""
        service_id = 1
        worker = db.worker_create(self.ctxt,
                                  resource_type='Volume',
                                  resource_id=fake.VOLUME_ID,
                                  status='creating',
                                  service_id=service_id)

        # Read it back to have the updated_at value
        worker = db.worker_get(self.ctxt, id=worker.id)
        claimed_worker = db.worker_get(self.ctxt, id=worker.id)

        time.sleep(0.1)
        # Simulate that this service starts processing this entry
        res = db.worker_claim_for_cleanup(self.ctxt, service_id,
                                          claimed_worker)
        self.assertEqual(1, res)

        res = db.worker_claim_for_cleanup(self.ctxt, service_id, worker)
        self.assertEqual(0, res)
        db_worker = db.worker_get(self.ctxt, id=worker.id)
        self._assertEqualObjects(claimed_worker, db_worker)
        self._assertEqualObjects(worker, db_worker, ['updated_at'])
        self.assertNotEqual(worker.updated_at, db_worker.updated_at)
コード例 #27
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
 def test_worker_create_no_subsecond(self, mock_utcnow):
     """Test basic creation of a worker record."""
     db.sqlalchemy.api.DB_SUPPORTS_SUBSECOND_RESOLUTION = False
     worker = db.worker_create(self.ctxt, **self.worker_fields)
     db_worker = db.worker_get(self.ctxt, id=worker.id)
     self._assertEqualObjects(worker, db_worker)
     self.assertEqual(0, db_worker.updated_at.microsecond)
コード例 #28
0
    def test_do_cleanup(self):
        """Basic successful cleanup."""
        vol = utils.create_volume(self.context, status='creating')
        db.worker_create(self.context,
                         status='creating',
                         resource_type='Volume',
                         resource_id=vol.id,
                         service_id=self.service.id)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        self.assertListEqual([], db.worker_get_all(self.context))
        vol.refresh()
        self.assertEqual('creating_cleaned', vol.status)
コード例 #29
0
    def test_init_host_clears_downloads(self):
        """Test that init_host will unwedge a volume stuck in downloading."""
        volume = tests_utils.create_volume(self.context, status='downloading',
                                           size=0, host=CONF.host)
        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)
        mock_clear = self.mock_object(self.volume.driver, 'clear_download')

        self.volume.init_host(service_id=service.Service.service_id)
        self.assertEqual(1, mock_clear.call_count)
        self.assertEqual(volume.id, mock_clear.call_args[0][1].id)
        volume.refresh()
        self.assertEqual("error", volume['status'])

        self.volume.delete_volume(self.context, volume=volume)
        self._assert_workers_are_removed()
コード例 #30
0
    def test_do_cleanup_revive_on_cleanup_fail(self, mock_clean):
        """Cleanup will revive a worker if cleanup fails."""
        vol = utils.create_volume(self.context, status='creating')
        db.worker_create(self.context,
                         status='creating',
                         resource_type='Volume',
                         resource_id=vol.id,
                         service_id=self.service.id)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))
        vol.refresh()
        self.assertEqual('creating', vol.status)
コード例 #31
0
    def test_do_cleanup_not_cleaning_already_claimed_by_us(self):
        """Basic cleanup that doesn't touch other thread's claimed works."""
        now = timeutils.utcnow()
        delta = timeutils.datetime.timedelta(seconds=1)
        original_time = now - delta
        # Creating the worker in the future, and then changing the in-memory
        # value of worker2.updated_at to an earlier time, we effectively
        # simulate that the worker entry was created in the past and that it
        # has been just updated between worker_get_all and trying
        # to claim a work for cleanup
        other_thread_claimed_time = now + delta
        vol = utils.create_volume(self.context, status='creating')
        worker1 = db.worker_create(self.context,
                                   status='creating',
                                   resource_type='Volume',
                                   resource_id=vol.id,
                                   service_id=self.service.id,
                                   updated_at=original_time)
        worker1 = db.worker_get(self.context, id=worker1.id)
        vol2 = utils.create_volume(self.context, status='deleting')
        worker2 = db.worker_create(self.context,
                                   status='deleting',
                                   resource_type='Volume',
                                   resource_id=vol2.id,
                                   service_id=self.service.id,
                                   updated_at=other_thread_claimed_time)
        worker2 = db.worker_get(self.context, id=worker2.id)
        # This with the mock below simulates worker2 was created in the past
        # and updated right between worker_get_all and worker_claim_for_cleanup
        worker2.updated_at = original_time

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        with mock.patch('cinder.manager.timeutils.utcnow', return_value=now),\
                mock.patch('cinder.db.worker_get_all') as get_all_mock:
            get_all_mock.return_value = [worker1, worker2]
            mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))
        self.assertEqual(worker2.id, workers[0].id)

        vol.refresh()
        self.assertEqual('creating_cleaned', vol.status)
        vol2.refresh()
        self.assertEqual('deleting', vol2.status)
コード例 #32
0
    def test_do_cleanup_keep_worker(self):
        """Cleanup on a resource that will remove worker when cleaning up."""
        vol = utils.create_volume(self.context, status='deleting')
        db.worker_create(self.context,
                         status='deleting',
                         resource_type='Volume',
                         resource_id=vol.id,
                         service_id=self.service.id)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id, keep_after_clean=True)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))
        vol.refresh()
        self.assertEqual('deleting_cleaned', vol.status)
コード例 #33
0
    def test_init_host_clears_uploads_in_use_volume(self, init_host_mock):
        """init_host will clean an in-use volume stuck in uploading."""
        volume = tests_utils.create_volume(self.context, status='uploading',
                                           size=0, host=CONF.host)

        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)

        fake_uuid = fakes.get_fake_uuid()
        tests_utils.attach_volume(self.context, volume.id, fake_uuid,
                                  'fake_host', '/dev/vda')
        self.volume.init_host(service_id=mock.sentinel.service_id)
        init_host_mock.assert_called_once_with(
            service_id=mock.sentinel.service_id, added_to_cluster=None)
        volume.refresh()
        self.assertEqual("in-use", volume.status)
        self._assert_workers_are_removed()
コード例 #34
0
    def test_do_cleanup_resource_changed_status(self):
        """Cleanup on a resource that's changed status."""
        vol = utils.create_volume(self.context, status='available')
        db.worker_create(self.context,
                         status='creating',
                         resource_type='Volume',
                         resource_id=vol.id,
                         service_id=self.service.id)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertListEqual([], workers)

        vol.refresh()
        self.assertEqual('available', vol.status)
コード例 #35
0
    def test_do_cleanup_resource_on_another_service(self):
        """Cleanup on a resource that's been claimed by other service."""
        vol = utils.create_volume(self.context, status='deleting')
        db.worker_create(self.context,
                         status='deleting',
                         resource_type='Volume',
                         resource_id=vol.id,
                         service_id=self.service.id + 1)

        clean_req = objects.CleanupRequest(service_id=self.service.id)
        mngr = FakeManager(self.service.id)
        mngr.do_cleanup(self.context, clean_req)

        workers = db.worker_get_all(self.context)
        self.assertEqual(1, len(workers))

        vol.refresh()
        self.assertEqual('deleting', vol.status)
コード例 #36
0
    def test_init_host_clears_uploads_in_use_volume(self, init_host_mock):
        """init_host will clean an in-use volume stuck in uploading."""
        volume = tests_utils.create_volume(self.context, status='uploading',
                                           size=0, host=CONF.host)

        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)

        fake_uuid = fakes.get_fake_uuid()
        tests_utils.attach_volume(self.context, volume.id, fake_uuid,
                                  'fake_host', '/dev/vda')
        self.volume.init_host(service_id=mock.sentinel.service_id)
        init_host_mock.assert_called_once_with(
            service_id=mock.sentinel.service_id, added_to_cluster=None)
        volume.refresh()
        self.assertEqual("in-use", volume.status)
        self._assert_workers_are_removed()
コード例 #37
0
    def test_init_host_clears_downloads(self, mock_cleanup_tmp_file):
        """Test that init_host will unwedge a volume stuck in downloading."""
        volume = tests_utils.create_volume(self.context, status='downloading',
                                           size=0, host=CONF.host)
        db.worker_create(self.context, resource_type='Volume',
                         resource_id=volume.id, status=volume.status,
                         service_id=self.service_id)
        mock_clear = self.mock_object(self.volume.driver, 'clear_download')

        self.volume.init_host(service_id=service.Service.service_id)
        self.assertEqual(1, mock_clear.call_count)
        self.assertEqual(volume.id, mock_clear.call_args[0][1].id)
        volume.refresh()
        self.assertEqual("error", volume['status'])
        mock_cleanup_tmp_file.assert_called_once_with(CONF.host)

        self.volume.delete_volume(self.context, volume=volume)
        self._assert_workers_are_removed()
コード例 #38
0
    def test_worker_claim_fails_status_change(self):
        """Test that claim fails if the work entry has changed its status."""
        worker = db.worker_create(self.ctxt, resource_type="Volume", resource_id=fake.VOLUME_ID, status="deleting")
        worker.status = "creating"

        res = db.worker_claim_for_cleanup(self.ctxt, 1, worker)
        self.assertEqual(0, res)

        db_worker = db.worker_get(self.ctxt, id=worker.id)
        self._assertEqualObjects(worker, db_worker, ["status"])
        self.assertIsNone(db_worker.service_id)
コード例 #39
0
    def test_create_volume_fails_with_creating_and_downloading_status(self):
        """Test init_host_with_service in case of volume.

        While the status of volume is 'creating' or 'downloading',
        volume process down.
        After process restarting this 'creating' status is changed to 'error'.
        """
        for status in ('creating', 'downloading'):
            volume = tests_utils.create_volume(self.context, status=status,
                                               size=0, host=CONF.host)

            db.worker_create(self.context, resource_type='Volume',
                             resource_id=volume.id, status=volume.status,
                             service_id=self.service_id)

            self.volume.init_host(service_id=service.Service.service_id)
            volume.refresh()

            self.assertEqual('error', volume['status'])
            self.volume.delete_volume(self.context, volume)
            self._assert_workers_are_removed()
コード例 #40
0
    def test_worker_claim(self):
        """Test worker claim of normal DB entry."""
        service_id = 1
        worker = db.worker_create(self.ctxt, resource_type="Volume", resource_id=fake.VOLUME_ID, status="deleting")

        res = db.worker_claim_for_cleanup(self.ctxt, service_id, worker)
        self.assertEqual(1, res)

        db_worker = db.worker_get(self.ctxt, id=worker.id)

        self._assertEqualObjects(worker, db_worker, ["updated_at"])
        self.assertEqual(service_id, db_worker.service_id)
        self.assertEqual(worker.service_id, db_worker.service_id)
コード例 #41
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
    def test_worker_claim_fails_status_change(self):
        """Test that claim fails if the work entry has changed its status."""
        worker = db.worker_create(self.ctxt,
                                  resource_type='Volume',
                                  resource_id=fake.VOLUME_ID,
                                  status='deleting')
        worker.status = 'creating'

        res = db.worker_claim_for_cleanup(self.ctxt, 1, worker)
        self.assertEqual(0, res)

        db_worker = db.worker_get(self.ctxt, id=worker.id)
        self._assertEqualObjects(worker, db_worker, ['status'])
        self.assertIsNone(db_worker.service_id)
コード例 #42
0
    def set_worker(self):
        worker = self.worker

        service_id = service.Service.service_id
        resource_type = self.__class__.__name__

        if worker:
            if worker.cleaning:
                return
        else:
            try:
                worker = db.worker_get(self._context,
                                       resource_type=resource_type,
                                       resource_id=self.id)
            except exception.WorkerNotFound:
                # If the call didn't come from an RPC call we still have to
                # create the entry in the DB.
                try:
                    self.worker = db.worker_create(self._context,
                                                   status=self.status,
                                                   resource_type=resource_type,
                                                   resource_id=self.id,
                                                   service_id=service_id)
                    return
                except exception.WorkerExists:
                    # If 2 cleanable operations are competing for this resource
                    # and the other one created the entry first that one won
                    raise exception.CleanableInUse(type=resource_type,
                                                   id=self.id)

        # If we have to claim this work or if the status has changed we have
        # to update DB.
        if (worker.service_id != service_id or worker.status != self.status):
            try:
                db.worker_update(self._context,
                                 worker.id,
                                 filters={
                                     'service_id': worker.service_id,
                                     'status': worker.status,
                                     'race_preventer': worker.race_preventer,
                                     'updated_at': worker.updated_at
                                 },
                                 service_id=service_id,
                                 status=self.status,
                                 orm_worker=worker)
            except exception.WorkerNotFound:
                self.worker = None
                raise exception.CleanableInUse(type=self.__class__.__name__,
                                               id=self.id)
        self.worker = worker
コード例 #43
0
    def test_worker_claim_fails_service_change(self):
        """Test that claim fails on worker service change."""
        failed_service = 1
        working_service = 2
        this_service = 3
        worker = db.worker_create(
            self.ctxt, resource_type="Volume", resource_id=fake.VOLUME_ID, status="deleting", service_id=working_service
        )

        worker.service_id = failed_service
        res = db.worker_claim_for_cleanup(self.ctxt, this_service, worker)
        self.assertEqual(0, res)
        db_worker = db.worker_get(self.ctxt, id=worker.id)
        self.assertEqual(working_service, db_worker.service_id)
コード例 #44
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
    def _create_workers(self, num, read_back=False, **fields):
        workers = []
        base_params = self.worker_fields.copy()
        base_params.update(fields)

        for i in range(num):
            params = base_params.copy()
            params['resource_id'] = self._uuid()
            workers.append(db.worker_create(self.ctxt, **params))

        if read_back:
            for i in range(len(workers)):
                workers[i] = db.worker_get(self.ctxt, id=workers[i].id)

        return workers
コード例 #45
0
    def _create_workers(self, num, read_back=False, **fields):
        workers = []
        base_params = self.worker_fields.copy()
        base_params.update(fields)

        for i in range(num):
            params = base_params.copy()
            params['resource_id'] = self._uuid()
            workers.append(db.worker_create(self.ctxt, **params))

        if read_back:
            for i in range(len(workers)):
                workers[i] = db.worker_get(self.ctxt, id=workers[i].id)

        return workers
コード例 #46
0
ファイル: cleanable.py プロジェクト: ebalduf/cinder-backports
    def set_worker(self):
        worker = self.worker

        service_id = service.Service.service_id
        resource_type = self.__class__.__name__

        if worker:
            if worker.cleaning:
                return
        else:
            try:
                worker = db.worker_get(self._context,
                                       resource_type=resource_type,
                                       resource_id=self.id)
            except exception.WorkerNotFound:
                # If the call didn't come from an RPC call we still have to
                # create the entry in the DB.
                try:
                    self.worker = db.worker_create(self._context,
                                                   status=self.status,
                                                   resource_type=resource_type,
                                                   resource_id=self.id,
                                                   service_id=service_id)
                    return
                except exception.WorkerExists:
                    # If 2 cleanable operations are competing for this resource
                    # and the other one created the entry first that one won
                    raise exception.CleanableInUse(type=resource_type,
                                                   id=self.id)

        # If we have to claim this work or if the status has changed we have
        # to update DB.
        if (worker.service_id != service_id or worker.status != self.status):
            try:
                db.worker_update(
                    self._context, worker.id,
                    filters={'service_id': worker.service_id,
                             'status': worker.status,
                             'race_preventer': worker.race_preventer,
                             'updated_at': worker.updated_at},
                    service_id=service_id,
                    status=self.status,
                    orm_worker=worker)
            except exception.WorkerNotFound:
                self.worker = None
                raise exception.CleanableInUse(type=self.__class__.__name__,
                                               id=self.id)
        self.worker = worker
コード例 #47
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
    def test_worker_claim(self):
        """Test worker claim of normal DB entry."""
        service_id = 1
        worker = db.worker_create(self.ctxt,
                                  resource_type='Volume',
                                  resource_id=fake.VOLUME_ID,
                                  status='deleting')

        res = db.worker_claim_for_cleanup(self.ctxt, service_id, worker)
        self.assertEqual(1, res)

        db_worker = db.worker_get(self.ctxt, id=worker.id)

        self._assertEqualObjects(worker, db_worker, ['updated_at'])
        self.assertEqual(service_id, db_worker.service_id)
        self.assertEqual(worker.service_id, db_worker.service_id)
コード例 #48
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
    def test_worker_claim_fails_service_change(self):
        """Test that claim fails on worker service change."""
        failed_service = 1
        working_service = 2
        this_service = 3
        worker = db.worker_create(self.ctxt,
                                  resource_type='Volume',
                                  resource_id=fake.VOLUME_ID,
                                  status='deleting',
                                  service_id=working_service)

        worker.service_id = failed_service
        res = db.worker_claim_for_cleanup(self.ctxt, this_service, worker)
        self.assertEqual(0, res)
        db_worker = db.worker_get(self.ctxt, id=worker.id)
        self.assertEqual(working_service, db_worker.service_id)
コード例 #49
0
    def test_worker_claim_same_service(self):
        """Test worker claim of a DB entry that has our service_id."""
        service_id = 1
        worker = db.worker_create(
            self.ctxt, resource_type="Volume", resource_id=fake.VOLUME_ID, status="deleting", service_id=service_id
        )
        # Read from DB to get updated_at field
        worker = db.worker_get(self.ctxt, id=worker.id)
        claimed_worker = db.worker_get(self.ctxt, id=worker.id)

        res = db.worker_claim_for_cleanup(self.ctxt, service_id, claimed_worker)
        self.assertEqual(1, res)

        db_worker = db.worker_get(self.ctxt, id=worker.id)

        self._assertEqualObjects(claimed_worker, db_worker)
        self._assertEqualObjects(worker, db_worker, ["updated_at"])
        self.assertNotEqual(worker.updated_at, db_worker.updated_at)
コード例 #50
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
    def test_worker_claim_same_service(self):
        """Test worker claim of a DB entry that has our service_id."""
        service_id = 1
        worker = db.worker_create(self.ctxt,
                                  resource_type='Volume',
                                  resource_id=fake.VOLUME_ID,
                                  status='deleting',
                                  service_id=service_id)
        # Read from DB to get updated_at field
        worker = db.worker_get(self.ctxt, id=worker.id)
        claimed_worker = db.worker_get(self.ctxt, id=worker.id)

        res = db.worker_claim_for_cleanup(self.ctxt, service_id,
                                          claimed_worker)
        self.assertEqual(1, res)

        db_worker = db.worker_get(self.ctxt, id=worker.id)

        self._assertEqualObjects(claimed_worker, db_worker)
        self._assertEqualObjects(worker, db_worker, ['updated_at'])
        self.assertNotEqual(worker.updated_at, db_worker.updated_at)
コード例 #51
0
 def test_worker_create_and_get(self):
     """Test basic creation of a worker record."""
     worker = db.worker_create(self.ctxt, **self.worker_fields)
     db_worker = db.worker_get(self.ctxt, id=worker.id)
     self._assertEqualObjects(worker, db_worker)
コード例 #52
0
 def test_worker_get_non_existent(self):
     """Check basic non existent worker record get method."""
     db.worker_create(self.ctxt, **self.worker_fields)
     self.assertRaises(exception.WorkerNotFound, db.worker_get,
                       self.ctxt, service_id='1', **self.worker_fields)
コード例 #53
0
ファイル: test_db_worker_api.py プロジェクト: makr123/cinder
 def test_worker_create_and_get(self):
     """Test basic creation of a worker record."""
     worker = db.worker_create(self.ctxt, **self.worker_fields)
     db_worker = db.worker_get(self.ctxt, id=worker.id)
     self._assertEqualObjects(worker, db_worker)