def test_get_flow_state(self): _lb, fd = p_utils.temporary_flow_detail(backend=self.backend) fd.state = states.FAILURE with contextlib.closing(self.backend.get_connection()) as conn: fd.update(conn.update_flow_details(fd)) s = storage.Storage(flow_detail=fd, backend=self.backend) self.assertEquals(s.get_flow_state(), states.FAILURE)
def test_save_and_get(self): s = storage.Storage() s.add_task('42', 'my task') s.save('42', 5) self.assertEquals(s.get('42'), 5) self.assertEquals(s.fetch_all(), {}) self.assertEquals(s.get_task_state('42'), states.SUCCESS)
def test_reset(self): s = storage.Storage() s.add_task('42', 'my task') s.save('42', 5) s.reset('42') self.assertEquals(s.get_task_state('42'), states.PENDING) with self.assertRaises(exceptions.NotFound): s.get('42')
def test_fetch_by_name(self): s = storage.Storage() s.add_task('42', 'my task') name = 'my result' s.set_result_mapping('42', {name: None}) s.save('42', 5) self.assertEquals(s.fetch(name), 5) self.assertEquals(s.fetch_all(), {name: 5})
def test_fetch_result_not_ready(self): s = storage.Storage() s.add_task('42', 'my task') name = 'my result' s.set_result_mapping('42', {name: None}) with self.assertRaises(exceptions.NotFound): s.get(name) self.assertEquals(s.fetch_all(), {})
def test_inject(self): s = storage.Storage() s.inject({'foo': 'bar', 'spam': 'eggs'}) self.assertEquals(s.fetch('spam'), 'eggs') self.assertEquals(s.fetch_all(), { 'foo': 'bar', 'spam': 'eggs', })
def test_save_multiple_results(self): s = storage.Storage() s.add_task('42', 'my task') s.set_result_mapping('42', {'foo': 0, 'bar': 1, 'whole': None}) s.save('42', ('spam', 'eggs')) self.assertEquals(s.fetch_all(), { 'foo': 'spam', 'bar': 'eggs', 'whole': ('spam', 'eggs') })
def test_add_task_fd(self): _lb, flow_detail = p_utils.temporary_flow_detail(self.backend) s = storage.Storage(backend=self.backend, flow_detail=flow_detail) s.add_task('42', 'my task', '3.11') td = flow_detail.find('42') self.assertIsNot(td, None) self.assertEquals(td.uuid, '42') self.assertEquals(td.name, 'my task') self.assertEquals(td.version, '3.11') self.assertEquals(td.state, states.PENDING)
def test_inject_resumed(self): s = self._get_storage() s.inject({'foo': 'bar', 'spam': 'eggs'}) # verify it's there self.assertEquals(s.fetch_all(), { 'foo': 'bar', 'spam': 'eggs', }) # imagine we are resuming, so we need to make new # storage from same flow details s2 = storage.Storage(s._flowdetail, backend=self.backend) # injected data should still be there: self.assertEquals(s2.fetch_all(), { 'foo': 'bar', 'spam': 'eggs', })
def _make_runtime(self, flow, initial_state=None): compilation = compiler.PatternCompiler(flow).compile() flow_detail = pu.create_flow_detail(flow) store = storage.Storage(flow_detail) # This ensures the tasks exist in storage... for task in compilation.execution_graph: store.ensure_atom(task) if initial_state: store.set_flow_state(initial_state) task_notifier = notifier.Notifier() task_executor = executor.SerialTaskExecutor() retry_executor = executor.SerialRetryExecutor() task_executor.start() self.addCleanup(task_executor.stop) r = runtime.Runtime(compilation, store, task_notifier, task_executor, retry_executor) r.compile() return r
def _make_runtime(self, flow, initial_state=None): compilation = compiler.PatternCompiler(flow).compile() flow_detail = pu.create_flow_detail(flow) store = storage.Storage(flow_detail) nodes_iter = compilation.execution_graph.nodes_iter(data=True) for node, node_attrs in nodes_iter: if node_attrs['kind'] in ('task', 'retry'): store.ensure_atom(node) if initial_state: store.set_flow_state(initial_state) atom_notifier = notifier.Notifier() task_executor = executor.SerialTaskExecutor() retry_executor = executor.SerialRetryExecutor() task_executor.start() self.addCleanup(task_executor.stop) r = runtime.Runtime(compilation, store, atom_notifier, task_executor, retry_executor) r.compile() return r
def storage(self): """The storage unit for this engine. NOTE(harlowja): the atom argument lookup strategy will change for this storage unit after :py:func:`~taskflow.engines.base.Engine.compile` has completed (since **only** after compilation is the actual structure known). Before :py:func:`~taskflow.engines.base.Engine.compile` has completed the atom argument lookup strategy lookup will be restricted to injected arguments **only** (this will **not** reflect the actual runtime lookup strategy, which typically will be, but is not always different). """ def _scope_fetcher(atom_name): if self._compiled: return self._runtime.fetch_scopes_for(atom_name) else: return None return storage.Storage(self._flow_detail, backend=self._backend, scope_fetcher=_scope_fetcher)
def test_fetch_meapped_args(self): s = storage.Storage() s.inject({'foo': 'bar', 'spam': 'eggs'}) self.assertEquals(s.fetch_mapped_args({'viking': 'spam'}), {'viking': 'eggs'})
def test_fetch_not_found_args(self): s = storage.Storage() s.inject({'foo': 'bar', 'spam': 'eggs'}) with self.assertRaises(exceptions.NotFound): s.fetch_mapped_args({'viking': 'helmet'})
def test_non_saving_storage(self): _lb, flow_detail = p_utils.temporary_flow_detail(self.backend) s = storage.Storage(flow_detail=flow_detail) s.ensure_atom(test_utils.NoopTask('my_task')) self.assertTrue(uuidutils.is_uuid_like(s.get_atom_uuid('my_task')))
def _get_storage(self, flow_detail=None): if flow_detail is None: _lb, flow_detail = p_utils.temporary_flow_detail(self.backend) return storage.Storage(flow_detail=flow_detail, backend=self.backend)
def test_save_and_get_other_state(self): s = storage.Storage() s.add_task('42', 'my task') s.save('42', 5, states.FAILURE) self.assertEquals(s.get('42'), 5) self.assertEquals(s.get_task_state('42'), states.FAILURE)
def test_unknown_task_by_name(self): s = storage.Storage() with self.assertRaisesRegexp(exceptions.NotFound, '^Unknown task name:'): s.get_uuid_by_name('42')
def test_flow_name_and_uuid(self): fd = logbook.FlowDetail(name='test-fd', uuid='aaaa') s = storage.Storage(flow_detail=fd) self.assertEquals(s.flow_name, 'test-fd') self.assertEquals(s.flow_uuid, 'aaaa')
def test_get_flow_state(self): fd = storage.temporary_flow_detail() fd.state = states.INTERRUPTED fd.save() s = storage.Storage(fd) self.assertEquals(s.get_flow_state(), states.INTERRUPTED)
def test_fetch_unknown_name(self): s = storage.Storage() with self.assertRaisesRegexp(exceptions.NotFound, "^Name 'xxx' is not mapped"): s.fetch('xxx')
def test_mapping_none(self): s = storage.Storage() s.add_task('42', 'my task') s.set_result_mapping('42', None) s.save('42', 5) self.assertEquals(s.fetch_all(), {})
def test_set_and_get_flow_state(self): s = storage.Storage() s.set_flow_state(states.SUCCESS) self.assertEquals(s.get_flow_state(), states.SUCCESS)
def test_get_non_existing_var(self): s = storage.Storage() s.add_task('42', 'my task') with self.assertRaises(exceptions.NotFound): s.get('42')
def _get_storage(self): _lb, flow_detail = p_utils.temporary_flow_detail(self.backend) return storage.Storage(backend=self.backend, flow_detail=flow_detail)
def test_task_by_name(self): s = storage.Storage() s.add_task('42', 'my task') self.assertEquals(s.get_uuid_by_name('my task'), '42')
def test_non_saving_storage(self): _lb, flow_detail = p_utils.temporary_flow_detail(self.backend) s = storage.Storage(flow_detail=flow_detail) # no backend s.add_task('42', 'my task') self.assertEquals(s.get_uuid_by_name('my task'), '42')
def test_get_state_of_unknown_task(self): s = storage.Storage() with self.assertRaisesRegexp(exceptions.NotFound, '^Unknown'): s.get_task_state('42')
def test_reset_unknown_task(self): s = storage.Storage() s.add_task('42', 'my task') self.assertEquals(s.reset('42'), None)
def test_add_task(self): s = storage.Storage() s.add_task('42', 'my task') self.assertEquals(s.get_task_state('42'), states.PENDING)