def test_wrapper_task_subtask_returns(self): """Test that execute methods' return values are processed properly.""" # Use internal _FunctorSubtask to make this easier. Bonus: testing # _FunctorSubtask at the same time. def returns_second_arg(wrapper, boolable): """Used to test various boolable single returns.""" return boolable # Various valid 'False' boolables - update not needed falseables = (0, '', [], {}, False) for falseable in falseables: txst = tx._FunctorSubtask(returns_second_arg, falseable) self.assertFalse(self.tx_subtask_invoke(txst, self.dwrap)) # Various valid 'True' boolables - update needed trueables = (1, 'string', [0], {'k': 'v'}, True) for trueable in trueables: txst = tx._FunctorSubtask(returns_second_arg, trueable) self.assertTrue(self.tx_subtask_invoke(txst, self.dwrap))
def test_wrapper_task_adds_and_replication(self): """Deferred replication of individual WrapperTasks with adds. Covers: - wrapper_tasks - get_wrapper - add_subtask - add_functor_subtask """ def wt_check(wt1, wt2, len1, len2=None, upto=None): """Assert that two WrapperTasks have the same Subtasks. :param wt1, wt2: The WrapperTask instances to compare. :param len1, len2: The expected lengths of the WrapperTask.subtasks of wt1 and wt2, respectively. If len2 is None, it is assumed to be the same as len1. :param upto: (Optional, int) If specified, only the first 'upto' Subtasks are compared. Otherwise, the subtask lists are compared up to the lesser of len1 and len2. """ if len2 is None: len2 = len1 self.assertEqual(len1, len(wt1.subtasks)) self.assertEqual(len2, len(wt2.subtasks)) if upto is None: upto = min(len1, len2) for i in range(upto): self.assertIs(wt1.subtasks[i], wt2.subtasks[i]) # "Functors" for easy subtask creation. Named so we can identify them. foo = lambda: None bar = lambda: None baz = lambda: None xyz = lambda: None abc = lambda: None # setUp's initialization of feed_task creates empty dict and common_tx self.assertEqual({}, self.feed_task._tx_by_uuid) self.assertEqual(0, len(self.feed_task._common_tx.subtasks)) # Asking for the feed does *not* replicate the WrapperTasks feed = self.feed_task.feed self.assertEqual({}, self.feed_task._tx_by_uuid) self.assertEqual(0, len(self.feed_task._common_tx.subtasks)) # Add to the FeedTask self.feed_task.add_subtask(tx._FunctorSubtask(foo)) self.feed_task.add_functor_subtask(bar) # Still does not replicate self.assertEqual({}, self.feed_task._tx_by_uuid) subtasks = self.feed_task._common_tx.subtasks # Make sure the subtasks are legit and in order self.assertEqual(2, len(subtasks)) self.assertIsInstance(subtasks[0], tx.Subtask) self.assertIsInstance(subtasks[1], tx.Subtask) # Yes, these are both _FunctorSubtasks, but the point is verifying that # they are in the right order. self.assertIs(foo, subtasks[0]._func) self.assertIs(bar, subtasks[1]._func) # Now call something that triggers replication wrap10 = self.feed_task.get_wrapper(feed[10].uuid) self.assertEqual(feed[10], wrap10) self.assertNotEqual({}, self.feed_task._tx_by_uuid) self.assertEqual({lwrap.uuid for lwrap in feed}, set(self.feed_task.wrapper_tasks.keys())) # Pick a couple of wrapper tasks at random. wt5, wt8 = (self.feed_task.wrapper_tasks[feed[i].uuid] for i in (5, 8)) # They should not be the same self.assertNotEqual(wt5, wt8) # Their subtasks should not refer to the same lists self.assertIsNot(wt5.subtasks, wt8.subtasks) # But they should have the same Subtasks (the same actual instances) wt_check(wt5, wt8, 2) # Adding more subtasks to the feed manager adds to all (and by the way, # we don't have to refetch the WrapperTasks). self.feed_task.add_functor_subtask(baz) wt_check(wt5, wt8, 3) self.assertIs(baz, wt5.subtasks[2]._func) # Adding to an individual WrapperTask just adds to that one wt5.add_functor_subtask(xyz) wt_check(wt5, wt8, 4, 3) self.assertIs(xyz, wt5.subtasks[3]._func) # And we can still add another to both afterward self.feed_task.add_functor_subtask(abc) wt_check(wt5, wt8, 5, 4, upto=3) # Check the last couple by hand self.assertIs(xyz, wt5.subtasks[3]._func) self.assertIs(wt5.subtasks[4], wt8.subtasks[3]) self.assertIs(abc, wt5.subtasks[4]._func)