def test_restore_in_progress_form_submitted_kills_old_jobs(self):
        """If the user submits a form somehow while a job is running, the job should be terminated
        """
        task_cache_id = restore_cache_key(ASYNC_RESTORE_CACHE_KEY_PREFIX, self.user.user_id)
        initial_sync_cache_id = restore_cache_key(RESTORE_CACHE_KEY_PREFIX, self.user.user_id, version='2.0')
        fake_cached_thing = 'fake-cached-thing'
        restore_config = self._restore_config(async=True)
        # pretend we have a task running
        restore_config.cache.set(task_cache_id, fake_cached_thing)
        restore_config.cache.set(initial_sync_cache_id, fake_cached_thing)

        form = """
        <data xmlns="http://openrosa.org/formdesigner/blah">
            <meta>
                <userID>{user_id}</userID>
            </meta>
        </data>
        """

        with mock.patch('corehq.form_processor.submission_post.revoke_celery_task') as revoke:
            # with a different user in the same domain, task doesn't get killed
            submit_form_locally(form.format(user_id="other_user"), self.domain)
            self.assertFalse(revoke.called)
            self.assertEqual(restore_config.cache.get(task_cache_id), fake_cached_thing)
            self.assertEqual(restore_config.cache.get(initial_sync_cache_id), fake_cached_thing)

            # task gets killed when the user submits a form
            submit_form_locally(form.format(user_id=self.user.user_id), self.domain)
            revoke.assert_called_with(fake_cached_thing)
            self.assertIsNone(restore_config.cache.get(task_cache_id))
            self.assertIsNone(restore_config.cache.get(initial_sync_cache_id))
Example #2
0
    def test_restore_in_progress_form_submitted_kills_old_jobs(self):
        """If the user submits a form somehow while a job is running, the job should be terminated
        """
        task_cache_id = restore_cache_key(ASYNC_RESTORE_CACHE_KEY_PREFIX, self.user.user_id)
        initial_sync_cache_id = restore_cache_key(RESTORE_CACHE_KEY_PREFIX, self.user.user_id, version='2.0')
        fake_cached_thing = 'fake-cached-thing'
        restore_config = self._restore_config(async=True)
        # pretend we have a task running
        restore_config.cache.set(task_cache_id, fake_cached_thing)
        restore_config.cache.set(initial_sync_cache_id, fake_cached_thing)

        form = """
        <data xmlns="http://openrosa.org/formdesigner/blah">
            <meta>
                <userID>{user_id}</userID>
            </meta>
        </data>
        """

        with mock.patch('corehq.form_processor.submission_post.revoke_celery_task') as revoke:
            # with a different user in the same domain, task doesn't get killed
            submit_form_locally(form.format(user_id="other_user"), self.domain)
            self.assertFalse(revoke.called)
            self.assertEqual(restore_config.cache.get(task_cache_id), fake_cached_thing)
            self.assertEqual(restore_config.cache.get(initial_sync_cache_id), fake_cached_thing)

            # task gets killed when the user submits a form
            submit_form_locally(form.format(user_id=self.user.user_id), self.domain)
            revoke.assert_called_with(fake_cached_thing)
            self.assertIsNone(restore_config.cache.get(task_cache_id))
            self.assertIsNone(restore_config.cache.get(initial_sync_cache_id))
Example #3
0
 def test_switch_restore_response(self):
     '''
     Ensures that when switching from using a FileRestoreResponse to a
     BlobRestoreResponse that we don't use the old FileRestoreResponse
     cache
     '''
     key1 = restore_cache_key('domain', 'prefix', 'user_id')
     with flag_enabled('BLOBDB_RESTORE'):
         key2 = restore_cache_key('domain', 'prefix', 'user_id')
     self.assertNotEqual(key1, key2)
Example #4
0
    def test_subsequent_syncs_when_job_complete(self):
        # First sync, return a timout. Ensure that the async_task_id gets set
        cache_id = restore_cache_key(ASYNC_RESTORE_CACHE_KEY_PREFIX,
                                     self.user.user_id)
        with mock.patch('casexml.apps.phone.restore.get_async_restore_payload'
                        ) as task:
            delay = mock.MagicMock()
            delay.id = 'random_task_id'
            delay.get = mock.MagicMock(
                side_effect=TimeoutError())  # task not finished
            task.delay.return_value = delay

            restore_config = self._restore_config(async=True)
            initial_payload = restore_config.get_payload()
            self.assertIsNotNone(restore_config.cache.get(cache_id))
            self.assertIsInstance(initial_payload, AsyncRestoreResponse)
            # new synclog should not have been created
            self.assertIsNone(restore_config.restore_state.current_sync_log)

        # Second sync, don't timeout (can't use AsyncResult in tests, so mock
        # the return value).
        file_restore_response = mock.MagicMock(
            return_value=FileRestoreResponse())
        with mock.patch.object(AsyncResult, 'get',
                               file_restore_response) as get_result:
            with mock.patch.object(AsyncResult, 'status', ASYNC_RESTORE_SENT):
                subsequent_restore = self._restore_config(async=True)
                self.assertIsNotNone(restore_config.cache.get(cache_id))
                subsequent_restore.get_payload()

                # if the task actually ran, the cache should now not have the task id,
                # however, the task is not run in this test. See `test_completed_task_deletes_cache`
                # self.assertIsNone(restore_config.cache.get(cache_id))

                get_result.assert_called_with(timeout=1)
Example #5
0
    def test_subsequent_syncs_when_job_complete(self):
        # First sync, return a timout. Ensure that the async_task_id gets set
        cache_id = restore_cache_key(ASYNC_RESTORE_CACHE_KEY_PREFIX, self.user.user_id)
        with mock.patch('casexml.apps.phone.restore.get_async_restore_payload') as task:
            delay = mock.MagicMock()
            delay.id = 'random_task_id'
            delay.get = mock.MagicMock(side_effect=TimeoutError())  # task not finished
            task.delay.return_value = delay

            restore_config = self._restore_config(async=True)
            initial_payload = restore_config.get_payload()
            self.assertIsNotNone(restore_config.cache.get(cache_id))
            self.assertIsInstance(initial_payload, AsyncRestoreResponse)
            # new synclog should not have been created
            self.assertIsNone(restore_config.restore_state.current_sync_log)

        # Second sync, don't timeout (can't use AsyncResult in tests, so mock
        # the return value).
        file_restore_response = mock.MagicMock(return_value=FileRestoreResponse())
        with mock.patch.object(AsyncResult, 'get', file_restore_response) as get_result:
            with mock.patch.object(AsyncResult, 'status', ASYNC_RESTORE_SENT):
                subsequent_restore = self._restore_config(async=True)
                self.assertIsNotNone(restore_config.cache.get(cache_id))
                subsequent_restore.get_payload()

                # if the task actually ran, the cache should now not have the task id,
                # however, the task is not run in this test. See `test_completed_task_deletes_cache`
                # self.assertIsNone(restore_config.cache.get(cache_id))

                get_result.assert_called_with(timeout=1)
Example #6
0
 def test_completed_task_deletes_cache(self):
     cache_id = restore_cache_key(ASYNC_RESTORE_CACHE_KEY_PREFIX,
                                  self.user.user_id)
     restore_config = self._restore_config(async=True)
     restore_config.cache.set(cache_id,
                              'im going to be deleted by the next command')
     get_async_restore_payload.delay(restore_config)
     self.assertIsNone(restore_config.cache.get(cache_id))
Example #7
0
def has_cached_payload(sync_log, version, prefix=RESTORE_CACHE_KEY_PREFIX):
    return bool(get_redis_default_cache().get(restore_cache_key(
        sync_log.domain,
        prefix,
        sync_log.user_id,
        version=version,
        sync_log_id=sync_log._id,
    )))
Example #8
0
 def test_restore_caches_cleared(self):
     cache = get_redis_default_cache()
     cache_key = restore_cache_key(RESTORE_CACHE_KEY_PREFIX, 'user_id', version="2.0")
     cache.set(cache_key, 'test-thing')
     self.assertEqual(cache.get(cache_key), 'test-thing')
     form = """
         <data xmlns="http://openrosa.org/formdesigner/blah">
             <meta>
                 <userID>{user_id}</userID>
             </meta>
         </data>
     """
     submit_form_locally(form.format(user_id='user_id'), DOMAIN)
     self.assertIsNone(cache.get(cache_key))
Example #9
0
 def test_restore_caches_cleared(self):
     cache = get_redis_default_cache()
     cache_key = restore_cache_key(RESTORE_CACHE_KEY_PREFIX, 'user_id', version="2.0")
     cache.set(cache_key, 'test-thing')
     self.assertEqual(cache.get(cache_key), 'test-thing')
     form = """
         <data xmlns="http://openrosa.org/formdesigner/blah">
             <meta>
                 <userID>{user_id}</userID>
             </meta>
         </data>
     """
     submit_form_locally(form.format(user_id='user_id'), DOMAIN)
     self.assertIsNone(cache.get(cache_key))
Example #10
0
 def test_completed_task_deletes_cache(self):
     cache_id = restore_cache_key(ASYNC_RESTORE_CACHE_KEY_PREFIX, self.user.user_id)
     restore_config = self._restore_config(async=True)
     restore_config.cache.set(cache_id, 'im going to be deleted by the next command')
     get_async_restore_payload.delay(restore_config)
     self.assertIsNone(restore_config.cache.get(cache_id))