Ejemplo n.º 1
0
class RepeaterFailureTest(BaseRepeaterTest):
    def setUp(self):
        super(RepeaterFailureTest, self).setUp()
        self.domain_name = "test-domain"
        self.domain = create_domain(self.domain_name)

        self.repeater = CaseRepeater(
            domain=self.domain_name,
            url='case-repeater-url',
        )
        self.repeater.save()
        self.post_xml(self.xform_xml, self.domain_name)

    def tearDown(self):
        self.domain.delete()
        self.repeater.delete()
        delete_all_repeat_records()
        super(RepeaterFailureTest, self).tearDown()

    @run_with_all_backends
    def test_get_payload_exception(self):
        repeat_record = self.repeater.register(
            CaseAccessors(self.domain_name).get_case(CASE_ID))
        with self.assertRaises(Exception):
            with patch.object(CaseRepeater,
                              'get_payload',
                              side_effect=Exception('Boom!')):
                repeat_record.fire()

        self.assertEquals(repeat_record.failure_reason, 'Boom!')
        self.assertFalse(repeat_record.succeeded)

    @run_with_all_backends
    def test_failure(self):
        repeat_record = self.repeater.register(
            CaseAccessors(self.domain_name).get_case(CASE_ID))
        with patch(
                'corehq.apps.repeaters.models.simple_post_with_cached_timeout',
                side_effect=Exception('Boom!')):
            repeat_record.fire()

        self.assertEquals(repeat_record.failure_reason, 'Boom!')
        self.assertFalse(repeat_record.succeeded)

        # Should be marked as successful after a successful run
        with patch(
                'corehq.apps.repeaters.models.simple_post_with_cached_timeout'
        ):
            repeat_record.fire()

        self.assertTrue(repeat_record.succeeded)
Ejemplo n.º 2
0
class RepeaterFailureTest(BaseRepeaterTest):

    def setUp(self):
        super(RepeaterFailureTest, self).setUp()
        self.domain_name = "test-domain"
        self.domain = create_domain(self.domain_name)

        self.repeater = CaseRepeater(
            domain=self.domain_name,
            url='case-repeater-url',
        )
        self.repeater.save()
        self.post_xml(self.xform_xml, self.domain_name)

    def tearDown(self):
        self.domain.delete()
        self.repeater.delete()
        delete_all_repeat_records()
        super(RepeaterFailureTest, self).tearDown()

    @run_with_all_backends
    def test_failure(self):
        repeat_record = self.repeater.register(CaseAccessors(self.domain_name).get_case(CASE_ID))
        with patch('corehq.apps.repeaters.models.simple_post_with_cached_timeout', side_effect=Exception('Boom!')):
            repeat_record.fire()

        self.assertEquals(repeat_record.failure_reason, 'Boom!')
        self.assertFalse(repeat_record.succeeded)

        # Should be marked as successful after a successful run
        with patch('corehq.apps.repeaters.models.simple_post_with_cached_timeout'):
            repeat_record.fire()

        self.assertTrue(repeat_record.succeeded)
Ejemplo n.º 3
0
class TestRepeaterFormat(BaseRepeaterTest):
    def setUp(self):
        self.domain = "test-domain"
        create_domain(self.domain)
        self.post_xml(xform_xml, self.domain)

        self.repeater = CaseRepeater(
            domain=self.domain,
            url='case-repeater-url',
            version=V1,
            format='new_format'
        )
        self.repeater.save()

    def tearDown(self):
        self.repeater.delete()
        XFormInstance.get(instance_id).delete()
        repeat_records = RepeatRecord.all()
        for repeat_record in repeat_records:
            repeat_record.delete()

    def test_new_format_same_name(self):
        with self.assertRaises(DuplicateFormatException):
            @RegisterGenerator(CaseRepeater, 'case_xml', 'XML', is_default=False)
            class NewCaseGenerator(BasePayloadGenerator):
                def get_payload(self, repeat_record, payload_doc):
                    return "some random case"

    def test_new_format_second_default(self):
        with self.assertRaises(DuplicateFormatException):
            @RegisterGenerator(CaseRepeater, 'rubbish', 'XML', is_default=True)
            class NewCaseGenerator(BasePayloadGenerator):
                def get_payload(self, repeat_record, payload_doc):
                    return "some random case"

    def test_new_format_payload(self):
        payload = "some random case"

        @RegisterGenerator(CaseRepeater, 'new_format', 'XML')
        class NewCaseGenerator(BasePayloadGenerator):
            def get_payload(self, repeat_record, payload_doc):
                return payload

        repeat_record = self.repeater.register(CommCareCase.get(case_id))
        with patch('corehq.apps.repeaters.models.simple_post_with_cached_timeout') as mock_post:
            repeat_record.fire()
            headers = self.repeater.get_headers(repeat_record)
            mock_post.assert_called_with(
                payload,
                self.repeater.url,
                headers=headers,
                force_send=False,
                timeout=POST_TIMEOUT,
            )
Ejemplo n.º 4
0
class RepeaterFailureTest(BaseRepeaterTest):

    def setUp(self):
        self.domain_name = "test-domain"
        self.domain = create_domain(self.domain_name)

        self.repeater = CaseRepeater(
            domain=self.domain_name,
            url='case-repeater-url',
            version=V1,
            format='other_format'
        )
        self.repeater.save()
        self.post_xml(xform_xml, self.domain)

    def tearDown(self):
        self.domain.delete()
        self.repeater.delete()
        repeat_records = RepeatRecord.all()
        for repeat_record in repeat_records:
            repeat_record.delete()

    def test_failure(self):
        payload = "some random case"

        @RegisterGenerator(CaseRepeater, 'other_format', 'XML')
        class NewCaseGenerator(BasePayloadGenerator):
            def get_payload(self, repeat_record, payload_doc):
                return payload

        repeat_record = self.repeater.register(CommCareCase.get(case_id))
        with patch('corehq.apps.repeaters.models.simple_post_with_cached_timeout', side_effect=Exception('Boom!')):
            repeat_record.fire()

        self.assertEquals(repeat_record.failure_reason, 'Boom!')
        self.assertFalse(repeat_record.succeeded)

        # Should be marked as successful after a successful run
        with patch('corehq.apps.repeaters.models.simple_post_with_cached_timeout'):
            repeat_record.fire()

        self.assertTrue(repeat_record.succeeded)
Ejemplo n.º 5
0
class RepeaterTest(BaseRepeaterTest):

    def setUp(self):
        super(RepeaterTest, self).setUp()
        self.domain = "test-domain"
        create_domain(self.domain)
        self.case_repeater = CaseRepeater(
            domain=self.domain,
            url='case-repeater-url',
        )
        self.case_repeater.save()
        self.form_repeater = FormRepeater(
            domain=self.domain,
            url='form-repeater-url',
        )
        self.form_repeater.save()
        self.log = []
        self.post_xml(self.xform_xml, self.domain)

    def tearDown(self):
        self.case_repeater.delete()
        self.form_repeater.delete()
        FormProcessorTestUtils.delete_all_cases_forms_ledgers(self.domain)
        delete_all_repeat_records()
        super(RepeaterTest, self).tearDown()

    @run_with_all_backends
    def test_skip_device_logs(self):
        devicelog_xml = XFORM_XML_TEMPLATE.format(DEVICE_LOG_XMLNS, USER_ID, '1234', '')
        self.post_xml(devicelog_xml, self.domain)
        repeat_records = RepeatRecord.all(domain=self.domain)
        for repeat_record in repeat_records:
            self.assertNotEqual(repeat_record.payload_id, '1234')

    @run_with_all_backends
    def test_repeater_failed_sends(self):
        """
        This tests records that fail are requeued later
        """
        def now():
            return datetime.utcnow()

        repeat_records = RepeatRecord.all(domain=self.domain, due_before=now())
        self.assertEqual(len(repeat_records), 2)

        for repeat_record in repeat_records:
            with patch(
                    'corehq.apps.repeaters.models.simple_post',
                    return_value=MockResponse(status_code=404, reason='Not Found')) as mock_post:
                repeat_record.fire()
                self.assertEqual(mock_post.call_count, 1)

        next_check_time = now() + timedelta(minutes=60)

        repeat_records = RepeatRecord.all(
            domain=self.domain,
            due_before=now() + timedelta(minutes=15),
        )
        self.assertEqual(len(repeat_records), 0)

        repeat_records = RepeatRecord.all(
            domain=self.domain,
            due_before=next_check_time,
        )
        self.assertEqual(len(repeat_records), 2)

    @run_with_all_backends
    def test_update_failure_next_check(self):
        now = datetime.utcnow()
        record = RepeatRecord(domain=self.domain, next_check=now)
        self.assertIsNone(record.last_checked)

        attempt = record.make_set_next_try_attempt(None)
        record.add_attempt(attempt)
        self.assertTrue(record.last_checked > now)
        self.assertEqual(record.next_check, record.last_checked + MIN_RETRY_WAIT)

    @run_with_all_backends
    def test_repeater_successful_send(self):

        repeat_records = RepeatRecord.all(domain=self.domain, due_before=datetime.utcnow())

        for repeat_record in repeat_records:
            with patch(
                    'corehq.apps.repeaters.models.simple_post',
                    return_value=MockResponse(status_code=200, reason='No Reason')) as mock_post:
                repeat_record.fire()
                self.assertEqual(mock_post.call_count, 1)
                mock_post.assert_any_call(
                    repeat_record.get_payload(),
                    repeat_record.repeater.get_url(repeat_record),
                    headers=repeat_record.repeater.get_headers(repeat_record),
                    timeout=POST_TIMEOUT,
                    auth=repeat_record.repeater.get_auth(),
                )

        # The following is pretty fickle and depends on which of
        #   - corehq.apps.repeaters.signals
        #   - casexml.apps.case.signals
        # gets loaded first.
        # This is deterministic but easily affected by minor code changes
        repeat_records = RepeatRecord.all(
            domain=self.domain,
            due_before=datetime.utcnow(),
        )
        for repeat_record in repeat_records:
            self.assertEqual(repeat_record.succeeded, True)
            self.assertEqual(repeat_record.next_check, None)

        self.assertEqual(len(self.repeat_records(self.domain)), 0)

        self.post_xml(self.update_xform_xml, self.domain)
        self.assertEqual(len(self.repeat_records(self.domain)), 2)

    @run_with_all_backends
    def test_check_repeat_records(self):
        self.assertEqual(len(RepeatRecord.all()), 2)

        with patch('corehq.apps.repeaters.models.simple_post') as mock_fire:
            check_repeaters()
            self.assertEqual(mock_fire.call_count, 2)

        with patch('corehq.apps.repeaters.models.simple_post') as mock_fire:
            check_repeaters()
            self.assertEqual(mock_fire.call_count, 0)

    @run_with_all_backends
    def test_repeat_record_status_check(self):
        self.assertEqual(len(RepeatRecord.all()), 2)

        # Do not trigger cancelled records
        for repeat_record in RepeatRecord.all():
            repeat_record.cancelled = True
            repeat_record.save()
        with patch('corehq.apps.repeaters.models.simple_post') as mock_fire:
            check_repeaters()
            self.assertEqual(mock_fire.call_count, 0)

        # trigger force send records if not cancelled and tries not exhausted
        for repeat_record in RepeatRecord.all():
            with patch('corehq.apps.repeaters.models.simple_post',
                       return_value=MockResponse(status_code=200, reason='')
                       ) as mock_fire:
                repeat_record.fire(force_send=True)
                self.assertEqual(mock_fire.call_count, 1)

        # all records should be in SUCCESS state after force try
        for repeat_record in RepeatRecord.all():
                self.assertEqual(repeat_record.state, RECORD_SUCCESS_STATE)
                self.assertEqual(repeat_record.overall_tries, 1)

        # not trigger records succeeded triggered after cancellation
        with patch('corehq.apps.repeaters.models.simple_post') as mock_fire:
            check_repeaters()
            self.assertEqual(mock_fire.call_count, 0)
            for repeat_record in RepeatRecord.all():
                self.assertEqual(repeat_record.state, RECORD_SUCCESS_STATE)

    @run_with_all_backends
    def test_process_repeat_record_locking(self):
        self.assertEqual(len(RepeatRecord.all()), 2)

        with patch('corehq.apps.repeaters.tasks.process_repeat_record') as mock_process:
            check_repeaters()
            self.assertEqual(mock_process.delay.call_count, 2)

        with patch('corehq.apps.repeaters.tasks.process_repeat_record') as mock_process:
            check_repeaters()
            self.assertEqual(mock_process.delay.call_count, 0)

        records = RepeatRecord.all()
        # Saving should unlock them again by changing the rev
        for record in records:
            record.save()

        with patch('corehq.apps.repeaters.tasks.process_repeat_record') as mock_process:
            check_repeaters()
            self.assertEqual(mock_process.delay.call_count, 2)

    @run_with_all_backends
    def test_automatic_cancel_repeat_record(self):
        repeat_record = self.case_repeater.register(CaseAccessors(self.domain).get_case(CASE_ID))
        repeat_record.overall_tries = 1
        with patch('corehq.apps.repeaters.models.simple_post', side_effect=Exception('Boom!')):
            repeat_record.fire()
        self.assertEqual(2, repeat_record.overall_tries)
        with patch('corehq.apps.repeaters.models.simple_post', side_effect=Exception('Boom!')):
            repeat_record.fire()
        self.assertEqual(True, repeat_record.cancelled)
        repeat_record.requeue()
        self.assertEqual(0, repeat_record.overall_tries)
        self.assertNotEqual(None, repeat_record.next_check)
Ejemplo n.º 6
0
class TestRepeaterFormat(BaseRepeaterTest):

    @classmethod
    def setUpClass(cls):
        super(TestRepeaterFormat, cls).setUpClass()
        cls.payload = 'some random case'

        @RegisterGenerator(CaseRepeater, 'new_format', 'XML')
        class NewCaseGenerator(BasePayloadGenerator):

            def get_payload(self, repeat_record, payload_doc):
                return cls.payload

    def setUp(self):
        super(TestRepeaterFormat, self).setUp()
        self.domain = "test-domain"
        create_domain(self.domain)
        self.post_xml(self.xform_xml, self.domain)

        self.repeater = CaseRepeater(
            domain=self.domain,
            url='case-repeater-url',
            format='new_format',
        )
        self.repeater.save()

    def tearDown(self):
        self.repeater.delete()
        FormProcessorTestUtils.delete_all_cases_forms_ledgers(self.domain)
        delete_all_repeat_records()
        super(TestRepeaterFormat, self).tearDown()

    def test_new_format_same_name(self):
        with self.assertRaises(DuplicateFormatException):
            @RegisterGenerator(CaseRepeater, 'case_xml', 'XML', is_default=False)
            class NewCaseGenerator(BasePayloadGenerator):

                def get_payload(self, repeat_record, payload_doc):
                    return self.payload

    def test_new_format_second_default(self):
        with self.assertRaises(DuplicateFormatException):
            @RegisterGenerator(CaseRepeater, 'rubbish', 'XML', is_default=True)
            class NewCaseGenerator(BasePayloadGenerator):

                def get_payload(self, repeat_record, payload_doc):
                    return self.payload

    @run_with_all_backends
    def test_new_format_payload(self):
        repeat_record = self.repeater.register(CaseAccessors(self.domain).get_case(CASE_ID))
        with patch('corehq.apps.repeaters.models.simple_post') as mock_post:
            repeat_record.fire()
            headers = self.repeater.get_headers(repeat_record)
            mock_post.assert_called_with(
                self.payload,
                self.repeater.url,
                headers=headers,
                timeout=POST_TIMEOUT,
                auth=self.repeater.get_auth(),
            )
Ejemplo n.º 7
0
class TestRepeaterFormat(BaseRepeaterTest):

    @classmethod
    def setUpClass(cls):
        super(TestRepeaterFormat, cls).setUpClass()
        cls.payload = 'some random case'

        @RegisterGenerator(CaseRepeater, 'new_format', 'XML')
        class NewCaseGenerator(BasePayloadGenerator):

            def get_payload(self, repeat_record, payload_doc):
                return cls.payload

    def setUp(self):
        super(TestRepeaterFormat, self).setUp()
        self.domain = "test-domain"
        create_domain(self.domain)
        self.post_xml(self.xform_xml, self.domain)

        self.repeater = CaseRepeater(
            domain=self.domain,
            url='case-repeater-url',
            format='new_format',
        )
        self.repeater.save()

    def tearDown(self):
        self.repeater.delete()
        FormProcessorTestUtils.delete_all_xforms(self.domain)
        delete_all_repeat_records()
        super(TestRepeaterFormat, self).tearDown()

    def test_new_format_same_name(self):
        with self.assertRaises(DuplicateFormatException):
            @RegisterGenerator(CaseRepeater, 'case_xml', 'XML', is_default=False)
            class NewCaseGenerator(BasePayloadGenerator):

                def get_payload(self, repeat_record, payload_doc):
                    return self.payload

    def test_new_format_second_default(self):
        with self.assertRaises(DuplicateFormatException):
            @RegisterGenerator(CaseRepeater, 'rubbish', 'XML', is_default=True)
            class NewCaseGenerator(BasePayloadGenerator):

                def get_payload(self, repeat_record, payload_doc):
                    return self.payload

    @run_with_all_backends
    def test_new_format_payload(self):
        repeat_record = self.repeater.register(CaseAccessors(self.domain).get_case(CASE_ID))
        with patch('corehq.apps.repeaters.models.simple_post_with_cached_timeout') as mock_post:
            repeat_record.fire()
            headers = self.repeater.get_headers(repeat_record)
            mock_post.assert_called_with(
                self.payload,
                self.repeater.url,
                headers=headers,
                force_send=False,
                timeout=POST_TIMEOUT,
            )