Пример #1
0
    def test_nested_context_works(self, queue_add_mock):
        """Ensure adding a job works."""
        from furious. async import Async
        from furious.context import Context

        with Context() as ctx:
            job = ctx.add('test', args=[1, 2])
            with Context() as ctx2:
                job2 = ctx2.add('test', args=[1, 2])

        self.assertIsInstance(job, Async)
        self.assertIsInstance(job2, Async)
        self.assertEqual(2, queue_add_mock.call_count)
Пример #2
0
    def test_marker_not_complete_when_start_fails(self, mock_insert,
                                                  context_from_id,
                                                  check_markers):
        """Ensure if the completion handler fails to start, that the marker
        does not get marked as complete.
        """

        complete_event = Mock()
        context = Context(id="contextid",
                          callbacks={'complete': complete_event})

        context_from_id.return_value = context

        check_markers.return_value = True, False

        async = Async('foo')
        async .update_options(context_id='contextid')
        FuriousCompletionMarker(id=async .context_id, complete=False).put()

        # Simulate the task failing to start
        mock_insert.side_effect = DeadlineExceededError()

        self.assertRaises(DeadlineExceededError, _completion_checker,
                          async .id, async .context_id)

        # Marker should not have been marked complete.
        current_marker = FuriousCompletionMarker.get_by_id(async .context_id)
        self.assertFalse(current_marker.complete)
Пример #3
0
    def test_results_with_no_tasks_loaded(self, get_multi_async):
        """Ensure results loads the tasks and yields them out when no tasks are
        cached.
        """
        marker1 = _build_marker(payload="1", status=1)
        marker2 = _build_marker(payload="2", status=1)
        marker3 = _build_marker(payload="3", status=1)

        future_set_1 = [
            _build_future(marker1),
            _build_future(marker2),
            _build_future(marker3)
        ]

        get_multi_async.return_value = future_set_1

        context = Context(_task_ids=["1", "2", "3"])
        context_result = ContextResult(context)

        results = list(context_result.items())

        results = sorted(results)

        self.assertEqual(results, [("1", "1"), ("2", "2"), ("3", "3")])

        self.assertEqual(context_result._task_cache, {
            "1": marker1,
            "2": marker2,
            "3": marker3
        })
Пример #4
0
    def test_markers_and_context_complete(self, mark, context_from_id,
                                          check_markers):
        """Ensure if all markers are complete that True is returned and
        nothing else is done.
        """
        async = Async('foo')
        async .update_options(context_id='contextid')

        complete_event = Mock()
        context = Context(id="contextid",
                          callbacks={'complete': complete_event})

        context_from_id.return_value = context

        marker = FuriousCompletionMarker(id="contextid", complete=True)
        marker.put()

        check_markers.return_value = True, False
        mark.return_value = True

        result = _completion_checker(async .id, async .context_id)

        self.assertTrue(result)

        self.assertFalse(complete_event.start.called)

        marker.key.delete()
Пример #5
0
    def test_add_jobs_to_multiple_queues(self):
        """Ensure adding jobs to multiple queues works as expected."""
        from google.appengine.api.taskqueue import Queue
        from furious.context import Context

        queue_registry = {}

        class AwesomeQueue(Queue):
            def __init__(self, *args, **kwargs):
                super(AwesomeQueue, self).__init__(*args, **kwargs)

                queue_registry[kwargs.get('name')] = self
                self._calls = []

            def add(self, *args, **kwargs):
                self._calls.append((args, kwargs))

        with patch('google.appengine.api.taskqueue.Queue', AwesomeQueue):
            with Context() as ctx:
                ctx.add('test', args=[1, 2], queue='A')
                ctx.add('test', args=[1, 2], queue='A')
                ctx.add('test', args=[1, 2], queue='B')
                ctx.add('test', args=[1, 2], queue='C')

        self.assertEqual(2, len(queue_registry['A']._calls[0][0][0]))
        self.assertEqual(1, len(queue_registry['B']._calls[0][0][0]))
        self.assertEqual(1, len(queue_registry['C']._calls[0][0][0]))
Пример #6
0
    def test_has_no_marker(self):
        """Ensure returns False when no marker found."""
        context_id = 1

        context = Context(id=context_id)
        context_result = ContextResult(context)

        self.assertIsNone(context_result._marker)
        self.assertFalse(context_result.has_errors())
Пример #7
0
    def test_added_to_correct_queue(self, queue_mock):
        """Ensure jobs are added to the correct queue."""
        from furious.context import Context

        with Context() as ctx:
            ctx.add('test', args=[1, 2], queue='A')
            ctx.add('test', args=[1, 2], queue='A')

        queue_mock.assert_called_once_with(name='A')
    def test_context_gets_one_id(self):
        """Ensure a new Context gets an id only generated once."""
        from furious.context import Context

        context = Context()

        id1 = context.id
        id2 = context.id
        self.assertEqual(id1, id2)
        self.assertEqual(context.id, id1)
Пример #9
0
    def test_add_multiple_jobs_to_context_works(self, queue_add_mock):
        """Ensure adding multiple jobs works."""
        from furious.context import Context

        with Context() as ctx:
            for _ in range(10):
                ctx.add('test', args=[1, 2])

        queue_add_mock.assert_called_once()
        self.assertEqual(10, len(queue_add_mock.call_args[0][0]))
Пример #10
0
    def test_no_task_ids(self, get_multi_async):
        """Ensure no results are yielded out when there are no task ids on the
        passed in context.
        """
        get_multi_async.return_value = []
        context = Context(_task_ids=[])

        results = list(iter_context_results(context))

        self.assertEqual(results, [])
Пример #11
0
    def test_add_job_to_context_works(self, queue_add_mock):
        """Ensure adding a job works."""
        from furious. async import Async
        from furious.context import Context

        with Context() as ctx:
            job = ctx.add('test', args=[1, 2])

        self.assertIsInstance(job, Async)
        queue_add_mock.assert_called_once()
    def test_add_job_to_context_works(self, queue_add_mock):
        """Ensure adding a job works."""
        from furious. async import Async
        from furious.context import Context

        with Context() as ctx:
            job = ctx.add('test', args=[1, 2])

        self.assertIsInstance(job, Async)
        self.assertEqual(1, ctx.insert_success)
        self.assertEqual(1, queue_add_mock.call_count)
    def test_id_added_to_options(self, uuid_patch):
        """Ensure random context id gets added to options."""
        from furious.context import Context

        id = 'random-id'
        uuid_patch.return_value.hex = id

        context = Context()

        self.assertEqual(context.id, id)
        self.assertEqual(context._options['id'], id)
    def test_to_dict_with_callbacks(self):
        """Ensure to_dict correctly encodes callbacks."""
        import copy

        from furious. async import Async
        from furious.context import Context

        options = {
            'id': 'someid',
            'context_id': 'contextid',
            'parent_id': 'parentid',
            'persistence_engine': 'persistence_engine',
            'callbacks': {
                'success':
                self.__class__.test_to_dict_with_callbacks,
                'failure':
                "failure_function",
                'exec':
                Async(target=dir,
                      id='blargh',
                      context_id='contextid',
                      parent_id='parentid')
            }
        }

        context = Context(**copy.deepcopy(options))

        # This stuff gets dumped out by to_dict().
        options.update({
            'id': 'someid',
            'insert_tasks': 'furious.context.context._insert_tasks',
            'persistence_engine': 'persistence_engine',
            '_tasks_inserted': False,
            '_task_ids': [],
            'callbacks': {
                'success': ("furious.tests.context.test_context."
                            "TestContext.test_to_dict_with_callbacks"),
                'failure':
                "failure_function",
                'exec': {
                    'job': ('dir', None, None),
                    'id': 'blargh',
                    'context_id': 'contextid',
                    'parent_id': 'parentid',
                    '_recursion': {
                        'current': 0,
                        'max': 100
                    },
                    '_type': 'furious.async.Async'
                }
            }
        })

        self.assertEqual(options, context.to_dict())
Пример #15
0
    def test_has_errors_with_marker_not_cached(self):
        """Ensure returns the value from the marker when not cached."""
        context_id = 1

        FuriousCompletionMarker(id=context_id, has_errors=True).put()

        context = Context(id=context_id)
        context_result = ContextResult(context)

        self.assertIsNone(context_result._marker)
        self.assertTrue(context_result.has_errors())

        context_result._marker.key.delete()
    def test_added_asyncs_get_context_id(self, queue_mock):
        """Ensure Asyncs added to context get context id."""
        from furious. async import Async
        from furious.context import Context

        asyncs = [Async('test', id=i) for i in xrange(100, 110)]

        with Context() as ctx:
            for async in asyncs:
                ctx.add(async)
                self.assertEqual(ctx.id, async .get_options()['_context_id'])

        self.assertEqual(10, ctx.insert_success)
    def test_persist_persists(self):
        """Calling persist with an engine persists the Context."""
        from furious.context import Context

        persistence_engine = Mock()
        persistence_engine.func_name = 'persistence_engine'
        persistence_engine.im_class.__name__ = 'engine'

        context = Context(persistence_engine=persistence_engine)

        context.persist()

        persistence_engine.store_context.assert_called_once_with(context)
Пример #18
0
    def test_save_context(self):
        """Ensure the passed in context gets serialized and set on the saved
        FuriousContext entity.
        """
        _id = "contextid"

        context = Context(id=_id)

        result = store_context(context)

        self.assertEqual(result.id(), _id)

        loaded_context = FuriousContext.from_id(result.id())

        self.assertEqual(context.to_dict(), loaded_context.to_dict())
Пример #19
0
    def test_keys_with_no_results(self, get_multi_async):
        """Ensure empty results are yielded out when there are no items to
        load but task ids are on the passed in context.
        """
        future_set_1 = [_build_future(), _build_future(), _build_future()]

        get_multi_async.return_value = future_set_1

        context = Context(_task_ids=["1", "2", "3"])

        results = list(iter_context_results(context))

        self.assertEqual(results[0], ("1", None))
        self.assertEqual(results[1], ("2", None))
        self.assertEqual(results[2], ("3", None))
Пример #20
0
    def test_add_task_fails(self, queue_add_mock):
        """Ensure insert_failed and insert_success are calculated correctly."""
        from google.appengine.api.taskqueue import TaskAlreadyExistsError
        from furious.context import Context

        def queue_add(tasks, transactional=False):
            if len(tasks) != 2:
                raise TaskAlreadyExistsError()

        queue_add_mock.side_effect = queue_add

        with Context() as ctx:
            ctx.add('test', args=[1, 2], queue='A')
            ctx.add('test', args=[1, 2], queue='B')
            ctx.add('test', args=[1, 2], queue='B')

        self.assertEqual(2, ctx.insert_success)
        self.assertEqual(1, ctx.insert_failed)
Пример #21
0
    def test_results_with_tasks_loaded_missing_result(self, get_multi_async):
        """Ensure results uses the cached tasks and yields them out when tasks
        are cached and there's no results.
        """
        marker1 = FuriousAsyncMarker()

        context = Context(_task_ids=["1", "2", "3"])
        context_result = ContextResult(context)

        context_result._task_cache = {"1": marker1, "2": None, "3": None}

        results = list(context_result.items())

        results = sorted(results)

        self.assertEqual(results, [("1", None), ("2", None), ("3", None)])

        self.assertFalse(get_multi_async.called)
Пример #22
0
    def test_more_results_than_batch_size(self, get_multi_async):
        """Ensure all the results are yielded out when more than the batch
        size.
        """
        marker1 = _build_marker(payload="1", status=1)
        marker2 = _build_marker(payload="2", status=1)
        marker3 = _build_marker(payload="3", status=1)

        future_set_1 = [_build_future(marker1), _build_future(marker2)]
        future_set_2 = [_build_future(marker3)]

        get_multi_async.side_effect = future_set_1, future_set_2

        context = Context(_task_ids=["1", "2", "3"])

        results = list(iter_context_results(context, batch_size=2))

        self.assertEqual(results[0], ("1", marker1))
        self.assertEqual(results[1], ("2", marker2))
        self.assertEqual(results[2], ("3", marker3))
Пример #23
0
    def test_results_with_tasks_loaded(self, get_multi_async):
        """Ensure results uses the cached tasks and yields them out when tasks
        are cached.
        """
        marker1 = _build_marker(payload="1", status=1)
        marker2 = _build_marker(payload="2", status=1)
        marker3 = _build_marker(payload="3", status=1)

        context = Context(_task_ids=["1", "2", "3"])
        context_result = ContextResult(context)

        context_result._task_cache = {"1": marker1, "2": marker2, "3": marker3}

        results = list(context_result.items())

        results = sorted(results)

        self.assertEqual(results, [("1", "1"), ("2", "2"), ("3", "3")])

        self.assertFalse(get_multi_async.called)
Пример #24
0
    def test_markers_complete(self, context_from_id, check_markers):
        """Ensure if all markers are complete that True is returned and the
        completion handler and cleanup tasks are triggered.
        """
        complete_event = Mock()
        context = Context(id="contextid",
                          callbacks={'complete': complete_event})

        context_from_id.return_value = context

        check_markers.return_value = True, False

        async = Async('foo')
        async .update_options(context_id='contextid')
        FuriousCompletionMarker(id=async .context_id, complete=False).put()

        result = _completion_checker(async .id, async .context_id)

        self.assertTrue(result)

        complete_event.start.assert_called_once_with(transactional=True)
Пример #25
0
    def test_to_dict(self):
        """Ensure to_dict returns a dictionary representation of the Context.
        """
        import copy

        from furious.context import Context

        options = {
            'persistence_engine': 'persistence_engine',
            'unkown': True,
        }

        context = Context(**copy.deepcopy(options))

        # This stuff gets dumped out by to_dict().
        options.update({
            'insert_tasks': 'furious.context.context._insert_tasks',
            '_tasks_inserted': False,
            '_task_ids': [],
        })

        self.assertEqual(options, context.to_dict())
Пример #26
0
    def test_markers_not_complete(self, context_from_id, check_markers):
        """Ensure if not all markers are complete that False is returned and
        the completion handler and cleanup tasks are not triggered.
        """
        complete_event = Mock()
        context = Context(id="contextid",
                          callbacks={'complete': complete_event})

        context_from_id.return_value = context

        check_markers.return_value = False, False

        async = Async('foo')
        async .update_options(context_id='contextid')

        result = _completion_checker(async .id, async .context_id)

        self.assertFalse(result)

        self.assertTrue(context_from_id.called)

        self.assertFalse(complete_event.start.called)
Пример #27
0
    def test_context_gets_assigned_id(self):
        """Ensure a new Context keeps its assigned id."""
        from furious.context import Context

        self.assertEqual('test_id_weee', Context(id='test_id_weee').id)
Пример #28
0
    def test_context_gets_id(self):
        """Ensure a new Context gets an id generated."""
        from furious.context import Context

        self.assertTrue(Context().id)
Пример #29
0
    def test_context_works(self):
        """Ensure using a Context as a context manager works."""
        from furious.context import Context

        with Context():
            pass
Пример #30
0
    def test_persist_with_no_engine(self):
        """Calling persist with no engine should blow up."""
        from furious.context import Context

        context = Context()
        self.assertRaises(RuntimeError, context.persist)