Explorar el Código

Fixes issue 4768. (#4790)

* Returning GroupResult's parent as tuple for correct serialization

* Adding test task to return a GropuResult

* Change assert to check parent is tuple and not the id because of change for issue #4768

* Add previously deleted assert to check the parent id is in the rult tuple, and to avoid coverage decrease
Josue Balandrano Coronel hace 6 años
padre
commit
6fd0d35434
Se han modificado 4 ficheros con 44 adiciones y 6 borrados
  1. 4 1
      celery/result.py
  2. 20 0
      t/integration/tasks.py
  3. 17 3
      t/integration/test_canvas.py
  4. 3 2
      t/unit/tasks/test_result.py

+ 4 - 1
celery/result.py

@@ -918,7 +918,10 @@ class GroupResult(ResultSet):
                                          ', '.join(r.id for r in self.results))
 
     def as_tuple(self):
-        return (self.id, self.parent), [r.as_tuple() for r in self.results]
+        return (
+            (self.id, self.parent and self.parent.as_tuple()),
+            [r.as_tuple() for r in self.results]
+        )
 
     @property
     def children(self):

+ 20 - 0
t/integration/tasks.py

@@ -158,3 +158,23 @@ def second_order_replace2(self, state=False):
         raise self.replace(new_task)
     else:
         redis_connection.rpush('redis-echo', 'Out B')
+
+
+@shared_task(bind=True)
+def build_chain_inside_task(self):
+    """Task to build a chain.
+
+    This task builds a chain and returns the chain's AsyncResult
+    to verify that Asyncresults are correctly converted into
+    serializable objects"""
+    test_chain = (
+        add.s(1, 1) |
+        add.s(2) |
+        group(
+            add.s(3),
+            add.s(4)
+        ) |
+        add.s(5)
+    )
+    result = test_chain()
+    return result

+ 17 - 3
t/integration/test_canvas.py

@@ -10,9 +10,9 @@ from celery.result import AsyncResult, GroupResult, ResultSet
 
 from .conftest import flaky, get_active_redis_channels, get_redis_connection
 from .tasks import (add, add_chord_to_chord, add_replaced, add_to_all,
-                    add_to_all_to_chord, collect_ids, delayed_sum,
-                    delayed_sum_with_soft_guard, identity, ids, print_unicode,
-                    redis_echo, second_order_replace1, tsum)
+                    add_to_all_to_chord, build_chain_inside_task, collect_ids,
+                    delayed_sum, delayed_sum_with_soft_guard, identity, ids,
+                    print_unicode, redis_echo, second_order_replace1, tsum)
 
 TIMEOUT = 120
 
@@ -188,6 +188,20 @@ class test_chain:
         result = c.get()
         assert result == 10
 
+    @flaky
+    def test_groupresult_serialization(self, manager):
+        """Test GroupResult is correctly serialized
+        to save in the result backend"""
+        try:
+            manager.app.backend.ensure_chords_allowed()
+        except NotImplementedError as e:
+            raise pytest.skip(e.args[0])
+
+        async_result = build_chain_inside_task.delay()
+        result = async_result.get()
+        assert len(result) == 2
+        assert isinstance(result[0][1], list)
+
 
 class test_result_set:
 

+ 3 - 2
t/unit/tasks/test_result.py

@@ -1005,9 +1005,10 @@ class test_tuples:
              for i in range(2)],
             parent
         )
-        (result_id, parent_id), group_results = result.as_tuple()
+        (result_id, parent_tuple), group_results = result.as_tuple()
         assert result_id == result.id
-        assert parent_id == parent.id
+        assert parent_tuple == parent.as_tuple()
+        assert parent_tuple[0][0] == parent.id
         assert isinstance(group_results, list)
         expected_grp_res = [(('async-result-{}'.format(i), None), None)
                             for i in range(2)]