Example #1
0
 def test_ensure_existing_task(self):
     _lb, flow_detail = p_utils.temporary_flow_detail(self.backend)
     td = logbook.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'))
Example #2
0
 def test_logbook_add_task_detail(self):
     lb_id = uuidutils.generate_uuid()
     lb_name = 'lb-%s' % (lb_id)
     lb = logbook.LogBook(name=lb_name, uuid=lb_id)
     fd = logbook.FlowDetail('test', uuid=uuidutils.generate_uuid())
     td = logbook.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')
Example #3
0
    def test_task_detail_meta_update(self):
        lb_id = uuidutils.generate_uuid()
        lb_name = 'lb-%s' % (lb_id)
        lb = logbook.LogBook(name=lb_name, uuid=lb_id)
        fd = logbook.FlowDetail('test', uuid=uuidutils.generate_uuid())
        lb.add(fd)
        td = logbook.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, logbook.TaskDetail)
Example #4
0
    def test_task_detail_with_failure(self):
        lb_id = uuidutils.generate_uuid()
        lb_name = 'lb-%s' % (lb_id)
        lb = logbook.LogBook(name=lb_name, uuid=lb_id)
        fd = logbook.FlowDetail('test', uuid=uuidutils.generate_uuid())
        lb.add(fd)
        td = logbook.TaskDetail("detail-1", uuid=uuidutils.generate_uuid())

        try:
            raise RuntimeError('Woot!')
        except Exception:
            td.failure = misc.Failure()

        fd.add(td)

        with contextlib.closing(self._get_connection()) as conn:
            conn.save_logbook(lb)
            conn.update_flow_details(fd)
            conn.update_task_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)
        failure = td2.failure
        self.assertEqual(failure.exception_str, 'Woot!')
        self.assertIs(failure.check(RuntimeError), RuntimeError)
        self.assertEqual(failure.traceback_str, td.failure.traceback_str)
Example #5
0
def _unformat_task_detail(uuid, td_data):
    td = logbook.TaskDetail(name=td_data['name'], uuid=uuid)
    td.state = td_data.get('state')
    td.results = td_data.get('results')
    td.failure = p_utils.failure_from_dict(td_data.get('failure'))
    td.meta = td_data.get('meta')
    td.version = td_data.get('version')
    return td
Example #6
0
 def _save_flowdetail_tasks(self, e_fd, flow_detail):
     for task_detail in flow_detail:
         e_td = e_fd.find(task_detail.uuid)
         if e_td is None:
             e_td = logbook.TaskDetail(name=task_detail.name,
                                       uuid=task_detail.uuid)
             e_fd.add(e_td)
         if task_detail.uuid not in self.backend.task_details:
             self.backend.task_details[task_detail.uuid] = e_td
         p_utils.task_details_merge(e_td, task_detail, deep_copy=True)
Example #7
0
def _convert_td_to_external(td):
    # Convert from sqlalchemy model -> external model, this allows us
    # to change the internal sqlalchemy model easily by forcing a defined
    # interface (that isn't the sqlalchemy model itself).
    td_c = logbook.TaskDetail(td.name, uuid=td.uuid)
    td_c.state = td.state
    td_c.results = td.results
    td_c.failure = td.failure
    td_c.meta = td.meta
    td_c.version = td.version
    return td_c
Example #8
0
    def test_task_detail_update_not_existing(self):
        lb_id = uuidutils.generate_uuid()
        lb_name = 'lb-%s' % (lb_id)
        lb = logbook.LogBook(name=lb_name, uuid=lb_id)
        fd = logbook.FlowDetail('test', uuid=uuidutils.generate_uuid())
        lb.add(fd)
        td = logbook.TaskDetail("detail-1", uuid=uuidutils.generate_uuid())
        fd.add(td)
        with contextlib.closing(self._get_connection()) as conn:
            conn.save_logbook(lb)

        td2 = logbook.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))
Example #9
0
 def test_flow_detail_lazy_fetch(self):
     lb_id = uuidutils.generate_uuid()
     lb_name = 'lb-%s' % (lb_id)
     lb = logbook.LogBook(name=lb_name, uuid=lb_id)
     fd = logbook.FlowDetail('test', uuid=uuidutils.generate_uuid())
     td = logbook.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))
Example #10
0
    def _add_task(self, uuid, task_name, task_version=None):
        """Add the task to storage.

        Task becomes known to storage by that name and uuid.
        Task state is set to PENDING.
        """
        def save_both(conn, td):
            """Saves the flow and the task detail with the same connection."""
            self._save_flow_detail(conn)
            self._save_task_detail(conn, td)

        # TODO(imelnikov): check that task with same uuid or
        # task name does not exist.
        td = logbook.TaskDetail(name=task_name, uuid=uuid)
        td.state = states.PENDING
        td.version = task_version
        self._flowdetail.add(td)
        self._with_connection(save_both, td)
        self._task_name_to_uuid[task_name] = uuid
Example #11
0
    def test_sequential_flow_two_tasks_with_resumption(self):
        flow = lf.Flow('lf-2-r').add(
            utils.SaveOrderTask(name='task1', provides='x1'),
            utils.SaveOrderTask(name='task2', provides='x2'))

        # Create FlowDetail as if we already run task1
        _lb, fd = p_utils.temporary_flow_detail(self.backend)
        td = logbook.TaskDetail(name='task1', uuid='42')
        td.state = states.SUCCESS
        td.results = 17
        fd.add(td)

        with contextlib.closing(self.backend.get_connection()) as conn:
            fd.update(conn.update_flow_details(fd))
            td.update(conn.update_task_details(td))

        engine = self._make_engine(flow, fd)
        engine.run()
        self.assertEqual(self.values, ['task2'])
        self.assertEqual(engine.storage.fetch_all(), {'x1': 17, 'x2': 5})
Example #12
0
    def test_task_detail_save(self):
        lb_id = uuidutils.generate_uuid()
        lb_name = 'lb-%s' % (lb_id)
        lb = logbook.LogBook(name=lb_name, uuid=lb_id)
        fd = logbook.FlowDetail('test', uuid=uuidutils.generate_uuid())
        lb.add(fd)
        td = logbook.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_task_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_task_details(td)
Example #13
0
    def test_sequential_flow_two_tasks_with_resumption(self):
        flow = lf.Flow('lf-2-r').add(
            utils.ProgressingTask(name='task1', provides='x1'),
            utils.ProgressingTask(name='task2', provides='x2'))

        # Create FlowDetail as if we already run task1
        lb, fd = p_utils.temporary_flow_detail(self.backend)
        td = logbook.TaskDetail(name='task1', uuid='42')
        td.state = states.SUCCESS
        td.results = 17
        fd.add(td)

        with contextlib.closing(self.backend.get_connection()) as conn:
            fd.update(conn.update_flow_details(fd))
            td.update(conn.update_atom_details(td))

        engine = self._make_engine(flow, fd)
        with utils.CaptureListener(engine, capture_flow=False) as capturer:
            engine.run()
        expected = ['task2.t RUNNING', 'task2.t SUCCESS(5)']
        self.assertEqual(expected, capturer.values)
        self.assertEqual(engine.storage.fetch_all(), {'x1': 17, 'x2': 5})
Example #14
0
    def _update_task_details(self, td, txn, create_missing=False):
        # Determine whether the desired data exists or not.
        td_path = paths.join(self.task_path, td.uuid)
        try:
            td_data, _zstat = self._client.get(td_path)
        except k_exc.NoNodeError:
            # Not-existent: create or raise exception.
            if create_missing:
                txn.create(td_path)
                e_td = logbook.TaskDetail(name=td.name, uuid=td.uuid)
            else:
                raise exc.NotFound("No task details found with id: %s" %
                                   td.uuid)
        else:
            # Existent: read it out.
            e_td = p_utils.unformat_task_detail(td.uuid,
                                                misc.decode_json(td_data))

        # Update and write it back
        e_td = p_utils.task_details_merge(e_td, td)
        td_data = p_utils.format_task_detail(e_td)
        txn.set_data(td_path, misc.binary_encode(jsonutils.dumps(td_data)))
        return e_td
Example #15
0
 def test_get_without_save(self):
     _lb, flow_detail = p_utils.temporary_flow_detail(self.backend)
     td = logbook.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'))