def test_ensure_existing_task(self): _lb, flow_detail = p_utils.temporary_flow_detail(self.backend) td = models.TaskDetail(name='my_task', uuid='42') flow_detail.add(td) s = self._get_storage(flow_detail) s.ensure_atom(test_utils.NoopTask('my_task')) self.assertEqual('42', s.get_atom_uuid('my_task'))
def test_logbook_add_task_detail(self): lb_id = uuidutils.generate_uuid() lb_name = 'lb-%s' % (lb_id) lb = models.LogBook(name=lb_name, uuid=lb_id) fd = models.FlowDetail('test', uuid=uuidutils.generate_uuid()) td = models.TaskDetail("detail-1", uuid=uuidutils.generate_uuid()) td.version = '4.2' fd.add(td) lb.add(fd) with contextlib.closing(self._get_connection()) as conn: conn.save_logbook(lb) with contextlib.closing(self._get_connection()) as conn: lb2 = conn.get_logbook(lb_id) self.assertEqual(1, len(lb2)) tasks = 0 for fd in lb: tasks += len(fd) self.assertEqual(1, tasks) with contextlib.closing(self._get_connection()) as conn: lb2 = conn.get_logbook(lb_id) fd2 = lb2.find(fd.uuid) td2 = fd2.find(td.uuid) self.assertIsNot(td2, None) self.assertEqual(td2.name, 'detail-1') self.assertEqual(td2.version, '4.2') self.assertEqual(td2.intention, states.EXECUTE)
def test_task_detail_with_failure(self): lb_id = uuidutils.generate_uuid() lb_name = 'lb-%s' % (lb_id) lb = models.LogBook(name=lb_name, uuid=lb_id) fd = models.FlowDetail('test', uuid=uuidutils.generate_uuid()) lb.add(fd) td = models.TaskDetail("detail-1", uuid=uuidutils.generate_uuid()) try: raise RuntimeError('Woot!') except Exception: td.failure = failure.Failure() fd.add(td) with contextlib.closing(self._get_connection()) as conn: conn.save_logbook(lb) conn.update_flow_details(fd) conn.update_atom_details(td) # Read failure back with contextlib.closing(self._get_connection()) as conn: lb2 = conn.get_logbook(lb_id) fd2 = lb2.find(fd.uuid) td2 = fd2.find(td.uuid) self.assertEqual(td2.failure.exception_str, 'Woot!') self.assertIs(td2.failure.check(RuntimeError), RuntimeError) self.assertEqual(td2.failure.traceback_str, td.failure.traceback_str) self.assertIsInstance(td2, models.TaskDetail)
def test_task_detail_meta_update(self): lb_id = uuidutils.generate_uuid() lb_name = 'lb-%s' % (lb_id) lb = models.LogBook(name=lb_name, uuid=lb_id) fd = models.FlowDetail('test', uuid=uuidutils.generate_uuid()) lb.add(fd) td = models.TaskDetail("detail-1", uuid=uuidutils.generate_uuid()) td.meta = {'test': 42} fd.add(td) with contextlib.closing(self._get_connection()) as conn: conn.save_logbook(lb) conn.update_flow_details(fd) conn.update_atom_details(td) td.meta['test'] = 43 with contextlib.closing(self._get_connection()) as conn: conn.update_atom_details(td) with contextlib.closing(self._get_connection()) as conn: lb2 = conn.get_logbook(lb_id) fd2 = lb2.find(fd.uuid) td2 = fd2.find(td.uuid) self.assertEqual(td2.meta.get('test'), 43) self.assertIsInstance(td2, models.TaskDetail)
def test_task_detail_update_not_existing(self): lb_id = uuidutils.generate_uuid() lb_name = 'lb-%s' % (lb_id) lb = models.LogBook(name=lb_name, uuid=lb_id) fd = models.FlowDetail('test', uuid=uuidutils.generate_uuid()) lb.add(fd) td = models.TaskDetail("detail-1", uuid=uuidutils.generate_uuid()) fd.add(td) with contextlib.closing(self._get_connection()) as conn: conn.save_logbook(lb) td2 = models.TaskDetail("detail-1", uuid=uuidutils.generate_uuid()) fd.add(td2) with contextlib.closing(self._get_connection()) as conn: conn.update_flow_details(fd) with contextlib.closing(self._get_connection()) as conn: lb2 = conn.get_logbook(lb.uuid) fd2 = lb2.find(fd.uuid) self.assertIsNotNone(fd2.find(td.uuid)) self.assertIsNotNone(fd2.find(td2.uuid))
def test_flow_detail_lazy_fetch(self): lb_id = uuidutils.generate_uuid() lb_name = 'lb-%s' % (lb_id) lb = models.LogBook(name=lb_name, uuid=lb_id) fd = models.FlowDetail('test', uuid=uuidutils.generate_uuid()) td = models.TaskDetail("detail-1", uuid=uuidutils.generate_uuid()) td.version = '4.2' fd.add(td) lb.add(fd) with contextlib.closing(self._get_connection()) as conn: conn.save_logbook(lb) with contextlib.closing(self._get_connection()) as conn: fd2 = conn.get_flow_details(fd.uuid, lazy=True) self.assertEqual(0, len(fd2)) self.assertEqual(1, len(fd))
def test_task_detail_save(self): lb_id = uuidutils.generate_uuid() lb_name = 'lb-%s' % (lb_id) lb = models.LogBook(name=lb_name, uuid=lb_id) fd = models.FlowDetail('test', uuid=uuidutils.generate_uuid()) lb.add(fd) td = models.TaskDetail("detail-1", uuid=uuidutils.generate_uuid()) fd.add(td) # Ensure we can't save it since its owning logbook hasn't been # saved (flow details/task details can not exist on their own without # their parent existing). with contextlib.closing(self._get_connection()) as conn: self.assertRaises(exc.NotFound, conn.update_flow_details, fd) self.assertRaises(exc.NotFound, conn.update_atom_details, td) # Ok now we should be able to save them. with contextlib.closing(self._get_connection()) as conn: conn.save_logbook(lb) conn.update_flow_details(fd) conn.update_atom_details(td)
def test_get_without_save(self): _lb, flow_detail = p_utils.temporary_flow_detail(self.backend) td = models.TaskDetail(name='my_task', uuid='42') flow_detail.add(td) s = self._get_storage(flow_detail) self.assertEqual('42', s.get_atom_uuid('my_task'))
def test_get_notification_recovery_workflow_details_raises_keyerror( self, mock_get_flows_for_book, mock_get_atoms_for_flow): notification = fakes.create_fake_notification( payload={ 'event': 'LIFECYCLE', 'instance_uuid': uuidsentinel.fake_ins, 'vir_domain_event': 'STOPPED_FAILED'}, source_host_uuid=uuidsentinel.fake_host, notification_uuid=uuidsentinel.fake_notification) fd = models.FlowDetail('test', uuid=notification.notification_uuid) atom1 = models.TaskDetail('StopInstanceTask', uuid=uuidsentinel.atom_id_1) atom1.meta = { 'progress': 1.0, 'progress_details': { 'at_progress': 1.0, 'details': { 'progress_details': [ {'timestamp': '2019-03-11 05:22:20.329171', 'message': 'Stopping instance: ' '87c8ebc3-2a70-49f0-9280-d34662dc203d', 'progress': 0.0}, {'timestamp': '2019-03-11 05:22:28.902665', 'message': "Stopped instance: " "'87c8ebc3-2a70-49f0-9280-d34662dc203d'", 'progress': 1.0}]}}} atom1.state = 'SUCCESS' atom2 = models.TaskDetail('ConfirmInstanceActiveTask', uuid=uuidsentinel.atom_id_2) atom2.meta = { 'progress': 1.0, 'progress_details': { 'at_progress': 1.0, 'details': { 'progress_details': [ {'timestamp': '2019-03-11 05:22:29.597303', 'message': "Confirming instance " "'87c8ebc3-2a70-49f0-9280-d34662dc203d' " "vm_state is ACTIVE", 'progress': 0.0}, {'timestamp': '2019-03-11 05:22:31.916620', 'message': "Confirmed instance " "'87c8ebc3-2a70-49f0-9280-d34662dc203d'" " vm_state is ACTIVE", 'progress': 1.0}] }}} atom2.state = 'SUCCESS' atom3 = models.TaskDetail('StartInstanceTask', uuid=uuidsentinel.atom_id_3) atom3.state = 'RUNNING' def fd_generator(): yield fd def atom_detail_generator(): for atom in [atom1, atom2, atom3]: yield atom flow_details = fd_generator() atom_details = atom_detail_generator() mock_get_flows_for_book.return_value = flow_details mock_get_atoms_for_flow.return_value = atom_details driver.PERSISTENCE_BACKEND = 'memory://' progress_details = ( self.taskflow_driver.get_notification_recovery_workflow_details( self.ctxt, 'auto', notification)) # list of NotificationProgressDetails object expected_result = [] expected_result.append(( fakes.create_fake_notification_progress_details( name=atom1.name, uuid=atom1.uuid, progress=atom1.meta['progress'], state=atom1.state, progress_details=atom1.meta['progress_details'] ['details']['progress_details']))) expected_result.append(( fakes.create_fake_notification_progress_details( name=atom2.name, uuid=atom2.uuid, progress=atom2.meta['progress'], state=atom2.state, progress_details=atom2.meta['progress_details'] ['details']['progress_details']))) self.assertIsNotNone(progress_details) mock_get_flows_for_book.assert_called_once() mock_get_atoms_for_flow.assert_called_once() self.assertObjectList(expected_result, progress_details)