def test_subscription_update_too_many(self, get_fitbit_data, get_fitbit_profile): get_fitbit_profile.return_value = 0 # Check that celery tasks get postponed if the rate limit is hit cat_id = getattr(TimeSeriesDataType, self.category) _type = TimeSeriesDataType.objects.filter(category=cat_id)[0] lock_id = 'fitapp.tasks-lock-{0}-{1}-{2}'.format( self.fbuser.fitbit_user, _type, self.date) exc = fitbit_exceptions.HTTPTooManyRequests(self._error_response()) exc.retry_after_secs = 21 def side_effect(*args, **kwargs): # Delete the cache lock after the first try and adjust the # get_fitbit_data mock to be successful cache.delete(lock_id) get_fitbit_data.side_effect = None get_fitbit_data.return_value = [{ 'dateTime': self.date, 'value': '34' }] raise exc get_fitbit_data.side_effect = side_effect category = getattr(TimeSeriesDataType, self.category) resources = TimeSeriesDataType.objects.filter(category=category) self.assertEqual(TimeSeriesData.objects.count(), 0) result = get_time_series_data.apply_async( (self.fbuser.fitbit_user, _type.category, _type.resource,), {'date': parser.parse(self.date)}) result.get() # Since celery is in eager mode, we expect a Retry exception first # and then a second task execution that is successful self.assertEqual(get_fitbit_data.call_count, 2) self.assertEqual(TimeSeriesData.objects.count(), 1) self.assertEqual(TimeSeriesData.objects.get().value, '34')
def test_subscription_update_too_many_retry(self, get_fitbit_data, mock_retry): # Check that retry is called with the right arguments exc = fitbit_exceptions.HTTPTooManyRequests(self._error_response()) exc.retry_after_secs = 21 get_fitbit_data.side_effect = exc # This return value is just to keep celery from throwing up mock_retry.return_value = Exception() category = getattr(TimeSeriesDataType, self.category) _type = TimeSeriesDataType.objects.filter(category=category)[0] self.assertEqual(TimeSeriesData.objects.count(), 0) result = get_time_series_data.apply_async( ( self.fbuser.fitbit_user, _type.category, _type.resource, ), {'date': parser.parse(self.date)}) # 22 = 21 + x ** 0 get_time_series_data.retry.assert_called_once_with(countdown=22, exc=exc) self.assertRaises(Exception, result.get) self.assertEqual(get_fitbit_data.call_count, 1) self.assertEqual(TimeSeriesData.objects.count(), 0)
def test_subscription_update_too_many(self, get_fitbit_data): # Check that celery tasks get postponed if the rate limit is hit cat_id = getattr(TimeSeriesDataType, self.category) _type = TimeSeriesDataType.objects.filter(category=cat_id)[0] lock_id = 'fitapp.tasks-lock-{0}-{1}-{2}'.format( self.fbuser.fitbit_user, _type, self.date) exc = fitbit_exceptions.HTTPTooManyRequests(self._error_response()) exc.retry_after_secs = 21 def side_effect(*args, **kwargs): # Delete the cache lock after the first try and adjust the # get_fitbit_data mock to be successful cache.delete(lock_id) get_fitbit_data.side_effect = None get_fitbit_data.return_value = [{ 'dateTime': self.date, 'value': '34' }] raise exc get_fitbit_data.side_effect = side_effect category = getattr(TimeSeriesDataType, self.category) resources = TimeSeriesDataType.objects.filter(category=category) self.assertEqual(TimeSeriesData.objects.count(), 0) result = get_time_series_data.apply_async( (self.fbuser.fitbit_user, _type.category, _type.resource,), {'date': parser.parse(self.date)}) result.get() # Since celery is in eager mode, we expect a Retry exception first # and then a second task execution that is successful self.assertEqual(get_fitbit_data.call_count, 2) self.assertEqual(TimeSeriesData.objects.count(), 1) self.assertEqual(TimeSeriesData.objects.get().value, '34')
def test_subscription_update_bad_request(self, get_fitbit_data): # Make sure bad requests for floors and elevation are ignored, # otherwise Reject exception is raised exc = fitbit_exceptions.HTTPBadRequest('HI') get_fitbit_data.side_effect = exc _type = TimeSeriesDataType.objects.get( category=TimeSeriesDataType.activities, resource='elevation') self.assertEqual(TimeSeriesData.objects.count(), 0) result = get_time_series_data.apply_async( ( self.fbuser.fitbit_user, _type.category, _type.resource, ), {'date': parser.parse(self.date)}) self.assertEqual(result.successful(), True) self.assertEqual(result.result, None) self.assertEqual(TimeSeriesData.objects.count(), 0) _type = TimeSeriesDataType.objects.get( category=TimeSeriesDataType.activities, resource='floors') result = get_time_series_data.apply_async( ( self.fbuser.fitbit_user, _type.category, _type.resource, ), {'date': parser.parse(self.date)}) self.assertEqual(result.successful(), True) self.assertEqual(result.result, None) self.assertEqual(TimeSeriesData.objects.count(), 0) _type = TimeSeriesDataType.objects.get( category=TimeSeriesDataType.activities, resource='steps') result = get_time_series_data.apply_async( ( self.fbuser.fitbit_user, _type.category, _type.resource, ), {'date': parser.parse(self.date)}) self.assertEqual(result.successful(), False) self.assertEqual(type(result.result), celery.exceptions.Reject) self.assertEqual(result.result.reason, exc) self.assertEqual(TimeSeriesData.objects.count(), 0)
def test_subscription_update_bad_request(self, get_fitbit_data): # Make sure bad requests for floors and elevation are ignored, # otherwise Reject exception is raised exc = fitbit_exceptions.HTTPBadRequest('HI') get_fitbit_data.side_effect = exc _type = TimeSeriesDataType.objects.get( category=TimeSeriesDataType.activities, resource='elevation') self.assertEqual(TimeSeriesData.objects.count(), 0) result = get_time_series_data.apply_async( (self.fbuser.fitbit_user, _type.category, _type.resource,), {'date': parser.parse(self.date)}) self.assertEqual(result.successful(), True) self.assertEqual(result.result, None) self.assertEqual(TimeSeriesData.objects.count(), 0) _type = TimeSeriesDataType.objects.get( category=TimeSeriesDataType.activities, resource='floors') result = get_time_series_data.apply_async( (self.fbuser.fitbit_user, _type.category, _type.resource,), {'date': parser.parse(self.date)}) self.assertEqual(result.successful(), True) self.assertEqual(result.result, None) self.assertEqual(TimeSeriesData.objects.count(), 0) _type = TimeSeriesDataType.objects.get( category=TimeSeriesDataType.activities, resource='steps') result = get_time_series_data.apply_async( (self.fbuser.fitbit_user, _type.category, _type.resource,), {'date': parser.parse(self.date)}) self.assertEqual(result.successful(), False) self.assertEqual(type(result.result), celery.exceptions.Reject) self.assertEqual(result.result.reason, exc) self.assertEqual(TimeSeriesData.objects.count(), 0)
def test_subscription_update_bad_resource(self): # Make sure a resource we don't have yet is handled res = get_time_series_data.apply_async( (self.fbuser.fitbit_user, 0, 'new_resource',), {'date': parser.parse(self.date)}) self.assertEqual(res.successful(), False) self.assertEqual(type(res.result), celery.exceptions.Reject) self.assertEqual( type(res.result.reason), TimeSeriesDataType.DoesNotExist) self.assertEqual( getattr(res.result.reason, 'message', res.result.reason.args[0]), 'TimeSeriesDataType matching query does not exist.') self.assertEqual(TimeSeriesData.objects.count(), 0)
def test_subscription_update_too_many_retry(self, get_fitbit_data, mock_retry): # Check that retry is called with the right arguments exc = fitbit_exceptions.HTTPTooManyRequests(self._error_response()) exc.retry_after_secs = 21 get_fitbit_data.side_effect = exc # This return value is just to keep celery from throwing up mock_retry.return_value = Exception() category = getattr(TimeSeriesDataType, self.category) _type = TimeSeriesDataType.objects.filter(category=category)[0] self.assertEqual(TimeSeriesData.objects.count(), 0) result = get_time_series_data.apply_async( (self.fbuser.fitbit_user, _type.category, _type.resource,), {'date': parser.parse(self.date)}) # 22 = 21 + x ** 0 get_time_series_data.retry.assert_called_once_with( countdown=22, exc=exc) self.assertRaises(Exception, result.get) self.assertEqual(get_fitbit_data.call_count, 1) self.assertEqual(TimeSeriesData.objects.count(), 0)