Best Python code snippet using localstack_python
test_dynamodb.py
Source:test_dynamodb.py
1# -*- coding: utf-8 -*-2from __future__ import absolute_import, unicode_literals3from decimal import Decimal4import pytest5from case import MagicMock, Mock, patch, sentinel, skip6from celery import states7from celery.backends import dynamodb as module8from celery.backends.dynamodb import DynamoDBBackend9from celery.exceptions import ImproperlyConfigured10from celery.five import string11@skip.unless_module('boto3')12class test_DynamoDBBackend:13 def setup(self):14 self._static_timestamp = Decimal(1483425566.52) # noqa15 self.app.conf.result_backend = 'dynamodb://'16 @property17 def backend(self):18 """:rtype: DynamoDBBackend"""19 return self.app.backend20 def test_init_no_boto3(self):21 prev, module.boto3 = module.boto3, None22 try:23 with pytest.raises(ImproperlyConfigured):24 DynamoDBBackend(app=self.app)25 finally:26 module.boto3 = prev27 def test_init_aws_credentials(self):28 with pytest.raises(ImproperlyConfigured):29 DynamoDBBackend(30 app=self.app,31 url='dynamodb://a:@'32 )33 def test_init_invalid_ttl_seconds_raises(self):34 with pytest.raises(ValueError):35 DynamoDBBackend(36 app=self.app,37 url='dynamodb://@?ttl_seconds=1d'38 )39 def test_get_client_explicit_endpoint(self):40 table_creation_path = \41 'celery.backends.dynamodb.DynamoDBBackend._get_or_create_table'42 with patch('boto3.client') as mock_boto_client, \43 patch(table_creation_path):44 self.app.conf.dynamodb_endpoint_url = 'http://my.domain.com:666'45 backend = DynamoDBBackend(46 app=self.app,47 url='dynamodb://@us-east-1'48 )49 client = backend._get_client()50 assert backend.client is client51 mock_boto_client.assert_called_once_with(52 'dynamodb',53 endpoint_url='http://my.domain.com:666',54 region_name='us-east-1'55 )56 assert backend.endpoint_url == 'http://my.domain.com:666'57 def test_get_client_local(self):58 table_creation_path = \59 'celery.backends.dynamodb.DynamoDBBackend._get_or_create_table'60 with patch('boto3.client') as mock_boto_client, \61 patch(table_creation_path):62 backend = DynamoDBBackend(63 app=self.app,64 url='dynamodb://@localhost:8000'65 )66 client = backend._get_client()67 assert backend.client is client68 mock_boto_client.assert_called_once_with(69 'dynamodb',70 endpoint_url='http://localhost:8000',71 region_name='us-east-1'72 )73 assert backend.endpoint_url == 'http://localhost:8000'74 def test_get_client_credentials(self):75 table_creation_path = \76 'celery.backends.dynamodb.DynamoDBBackend._get_or_create_table'77 with patch('boto3.client') as mock_boto_client, \78 patch(table_creation_path):79 backend = DynamoDBBackend(80 app=self.app,81 url='dynamodb://key:secret@test'82 )83 client = backend._get_client()84 assert client is backend.client85 mock_boto_client.assert_called_once_with(86 'dynamodb',87 aws_access_key_id='key',88 aws_secret_access_key='secret',89 region_name='test'90 )91 assert backend.aws_region == 'test'92 @patch('boto3.client')93 @patch('celery.backends.dynamodb.DynamoDBBackend._get_or_create_table')94 @patch('celery.backends.dynamodb.DynamoDBBackend._validate_ttl_methods')95 @patch('celery.backends.dynamodb.DynamoDBBackend._set_table_ttl')96 def test_get_client_time_to_live_called(97 self,98 mock_set_table_ttl,99 mock_validate_ttl_methods,100 mock_get_or_create_table,101 mock_boto_client,102 ):103 backend = DynamoDBBackend(104 app=self.app,105 url='dynamodb://key:secret@test?ttl_seconds=30'106 )107 backend._get_client()108 mock_validate_ttl_methods.assert_called_once()109 mock_set_table_ttl.assert_called_once()110 def test_get_or_create_table_not_exists(self):111 self.backend._client = MagicMock()112 mock_create_table = self.backend._client.create_table = MagicMock()113 mock_describe_table = self.backend._client.describe_table = \114 MagicMock()115 mock_describe_table.return_value = {116 'Table': {117 'TableStatus': 'ACTIVE'118 }119 }120 self.backend._get_or_create_table()121 mock_create_table.assert_called_once_with(122 **self.backend._get_table_schema()123 )124 def test_get_or_create_table_already_exists(self):125 from botocore.exceptions import ClientError126 self.backend._client = MagicMock()127 mock_create_table = self.backend._client.create_table = MagicMock()128 client_error = ClientError(129 {130 'Error': {131 'Code': 'ResourceInUseException',132 'Message': 'Table already exists: {}'.format(133 self.backend.table_name134 )135 }136 },137 'CreateTable'138 )139 mock_create_table.side_effect = client_error140 mock_describe_table = self.backend._client.describe_table = \141 MagicMock()142 mock_describe_table.return_value = {143 'Table': {144 'TableStatus': 'ACTIVE'145 }146 }147 self.backend._get_or_create_table()148 mock_describe_table.assert_called_once_with(149 TableName=self.backend.table_name150 )151 def test_wait_for_table_status(self):152 self.backend._client = MagicMock()153 mock_describe_table = self.backend._client.describe_table = \154 MagicMock()155 mock_describe_table.side_effect = [156 {'Table': {157 'TableStatus': 'CREATING'158 }},159 {'Table': {160 'TableStatus': 'SOME_STATE'161 }}162 ]163 self.backend._wait_for_table_status(expected='SOME_STATE')164 assert mock_describe_table.call_count == 2165 def test_has_ttl_none_returns_none(self):166 self.backend.time_to_live_seconds = None167 assert self.backend._has_ttl() is None168 def test_has_ttl_lt_zero_returns_false(self):169 self.backend.time_to_live_seconds = -1170 assert self.backend._has_ttl() is False171 def test_has_ttl_gte_zero_returns_true(self):172 self.backend.time_to_live_seconds = 30173 assert self.backend._has_ttl() is True174 def test_validate_ttl_methods_present_returns_none(self):175 self.backend._client = MagicMock()176 assert self.backend._validate_ttl_methods() is None177 def test_validate_ttl_methods_missing_raise(self):178 self.backend._client = MagicMock()179 delattr(self.backend._client, 'describe_time_to_live')180 delattr(self.backend._client, 'update_time_to_live')181 with pytest.raises(AttributeError):182 self.backend._validate_ttl_methods()183 with pytest.raises(AttributeError):184 self.backend._validate_ttl_methods()185 def test_set_table_ttl_describe_time_to_live_fails_raises(self):186 from botocore.exceptions import ClientError187 self.backend.time_to_live_seconds = -1188 self.backend._client = MagicMock()189 mock_describe_time_to_live = \190 self.backend._client.describe_time_to_live = MagicMock()191 client_error = ClientError(192 {193 'Error': {194 'Code': 'Foo',195 'Message': 'Bar',196 }197 },198 'DescribeTimeToLive'199 )200 mock_describe_time_to_live.side_effect = client_error201 with pytest.raises(ClientError):202 self.backend._set_table_ttl()203 def test_set_table_ttl_enable_when_disabled_succeeds(self):204 self.backend.time_to_live_seconds = 30205 self.backend._client = MagicMock()206 mock_update_time_to_live = self.backend._client.update_time_to_live = \207 MagicMock()208 mock_describe_time_to_live = \209 self.backend._client.describe_time_to_live = MagicMock()210 mock_describe_time_to_live.return_value = {211 'TimeToLiveDescription': {212 'TimeToLiveStatus': 'DISABLED',213 'AttributeName': self.backend._ttl_field.name214 }215 }216 self.backend._set_table_ttl()217 mock_describe_time_to_live.assert_called_once_with(218 TableName=self.backend.table_name219 )220 mock_update_time_to_live.assert_called_once()221 def test_set_table_ttl_enable_when_enabled_with_correct_attr_succeeds(self):222 self.backend.time_to_live_seconds = 30223 self.backend._client = MagicMock()224 self.backend._client.update_time_to_live = MagicMock()225 mock_describe_time_to_live = \226 self.backend._client.describe_time_to_live = MagicMock()227 mock_describe_time_to_live.return_value = {228 'TimeToLiveDescription': {229 'TimeToLiveStatus': 'ENABLED',230 'AttributeName': self.backend._ttl_field.name231 }232 }233 self.backend._set_table_ttl()234 mock_describe_time_to_live.assert_called_once_with(235 TableName=self.backend.table_name236 )237 def test_set_table_ttl_enable_when_currently_disabling_raises(self):238 from botocore.exceptions import ClientError239 self.backend.time_to_live_seconds = 30240 self.backend._client = MagicMock()241 mock_update_time_to_live = self.backend._client.update_time_to_live = \242 MagicMock()243 client_error = ClientError(244 {245 'Error': {246 'Code': 'ValidationException',247 'Message': (248 'Time to live has been modified multiple times '249 'within a fixed interval'250 )251 }252 },253 'UpdateTimeToLive'254 )255 mock_update_time_to_live.side_effect = client_error256 mock_describe_time_to_live = \257 self.backend._client.describe_time_to_live = MagicMock()258 mock_describe_time_to_live.return_value = {259 'TimeToLiveDescription': {260 'TimeToLiveStatus': 'DISABLING',261 'AttributeName': self.backend._ttl_field.name262 }263 }264 with pytest.raises(ClientError):265 self.backend._set_table_ttl()266 def test_set_table_ttl_enable_when_enabled_with_wrong_attr_raises(self):267 from botocore.exceptions import ClientError268 self.backend.time_to_live_seconds = 30269 self.backend._client = MagicMock()270 mock_update_time_to_live = self.backend._client.update_time_to_live = \271 MagicMock()272 wrong_attr_name = self.backend._ttl_field.name + 'x'273 client_error = ClientError(274 {275 'Error': {276 'Code': 'ValidationException',277 'Message': (278 'TimeToLive is active on a different AttributeName: '279 'current AttributeName is {}'280 ).format(wrong_attr_name)281 }282 },283 'UpdateTimeToLive'284 )285 mock_update_time_to_live.side_effect = client_error286 mock_describe_time_to_live = \287 self.backend._client.describe_time_to_live = MagicMock()288 mock_describe_time_to_live.return_value = {289 'TimeToLiveDescription': {290 'TimeToLiveStatus': 'ENABLED',291 'AttributeName': self.backend._ttl_field.name + 'x'292 }293 }294 with pytest.raises(ClientError):295 self.backend._set_table_ttl()296 def test_set_table_ttl_disable_when_disabled_succeeds(self):297 self.backend.time_to_live_seconds = -1298 self.backend._client = MagicMock()299 self.backend._client.update_time_to_live = MagicMock()300 mock_describe_time_to_live = \301 self.backend._client.describe_time_to_live = MagicMock()302 mock_describe_time_to_live.return_value = {303 'TimeToLiveDescription': {304 'TimeToLiveStatus': 'DISABLED'305 }306 }307 self.backend._set_table_ttl()308 mock_describe_time_to_live.assert_called_once_with(309 TableName=self.backend.table_name310 )311 def test_set_table_ttl_disable_when_currently_enabling_raises(self):312 from botocore.exceptions import ClientError313 self.backend.time_to_live_seconds = -1314 self.backend._client = MagicMock()315 mock_update_time_to_live = self.backend._client.update_time_to_live = \316 MagicMock()317 client_error = ClientError(318 {319 'Error': {320 'Code': 'ValidationException',321 'Message': (322 'Time to live has been modified multiple times '323 'within a fixed interval'324 )325 }326 },327 'UpdateTimeToLive'328 )329 mock_update_time_to_live.side_effect = client_error330 mock_describe_time_to_live = \331 self.backend._client.describe_time_to_live = MagicMock()332 mock_describe_time_to_live.return_value = {333 'TimeToLiveDescription': {334 'TimeToLiveStatus': 'ENABLING',335 'AttributeName': self.backend._ttl_field.name336 }337 }338 with pytest.raises(ClientError):339 self.backend._set_table_ttl()340 def test_prepare_get_request(self):341 expected = {342 'TableName': u'celery',343 'Key': {u'id': {u'S': u'abcdef'}}344 }345 assert self.backend._prepare_get_request('abcdef') == expected346 def test_prepare_put_request(self):347 expected = {348 'TableName': u'celery',349 'Item': {350 u'id': {u'S': u'abcdef'},351 u'result': {u'B': u'val'},352 u'timestamp': {353 u'N': str(Decimal(self._static_timestamp))354 }355 }356 }357 with patch('celery.backends.dynamodb.time', self._mock_time):358 result = self.backend._prepare_put_request('abcdef', 'val')359 assert result == expected360 def test_prepare_put_request_with_ttl(self):361 ttl = self.backend.time_to_live_seconds = 30362 expected = {363 'TableName': u'celery',364 'Item': {365 u'id': {u'S': u'abcdef'},366 u'result': {u'B': u'val'},367 u'timestamp': {368 u'N': str(Decimal(self._static_timestamp))369 },370 u'ttl': {371 u'N': str(int(self._static_timestamp + ttl))372 }373 }374 }375 with patch('celery.backends.dynamodb.time', self._mock_time):376 result = self.backend._prepare_put_request('abcdef', 'val')377 assert result == expected378 def test_item_to_dict(self):379 boto_response = {380 'Item': {381 'id': {382 'S': sentinel.key383 },384 'result': {385 'B': sentinel.value386 },387 'timestamp': {388 'N': Decimal(1)389 }390 }391 }392 converted = self.backend._item_to_dict(boto_response)393 assert converted == {394 'id': sentinel.key,395 'result': sentinel.value,396 'timestamp': Decimal(1)397 }398 def test_get(self):399 self.backend._client = Mock(name='_client')400 self.backend._client.get_item = MagicMock()401 assert self.backend.get('1f3fab') is None402 self.backend.client.get_item.assert_called_once_with(403 Key={u'id': {u'S': u'1f3fab'}},404 TableName='celery'405 )406 def _mock_time(self):407 return self._static_timestamp408 def test_set(self):409 self.backend._client = MagicMock()410 self.backend._client.put_item = MagicMock()411 # should return None412 with patch('celery.backends.dynamodb.time', self._mock_time):413 assert self.backend._set_with_state(sentinel.key, sentinel.value, states.SUCCESS) is None414 assert self.backend._client.put_item.call_count == 1415 _, call_kwargs = self.backend._client.put_item.call_args416 expected_kwargs = {417 'Item': {418 u'timestamp': {u'N': str(self._static_timestamp)},419 u'id': {u'S': string(sentinel.key)},420 u'result': {u'B': sentinel.value}421 },422 'TableName': 'celery'423 }424 assert call_kwargs['Item'] == expected_kwargs['Item']425 assert call_kwargs['TableName'] == 'celery'426 def test_set_with_ttl(self):427 ttl = self.backend.time_to_live_seconds = 30428 self.backend._client = MagicMock()429 self.backend._client.put_item = MagicMock()430 # should return None431 with patch('celery.backends.dynamodb.time', self._mock_time):432 assert self.backend._set_with_state(sentinel.key, sentinel.value, states.SUCCESS) is None433 assert self.backend._client.put_item.call_count == 1434 _, call_kwargs = self.backend._client.put_item.call_args435 expected_kwargs = {436 'Item': {437 u'timestamp': {u'N': str(self._static_timestamp)},438 u'id': {u'S': string(sentinel.key)},439 u'result': {u'B': sentinel.value},440 u'ttl': {u'N': str(int(self._static_timestamp + ttl))},441 },442 'TableName': 'celery'443 }444 assert call_kwargs['Item'] == expected_kwargs['Item']445 assert call_kwargs['TableName'] == 'celery'446 def test_delete(self):447 self.backend._client = Mock(name='_client')448 mocked_delete = self.backend._client.delete = Mock('client.delete')449 mocked_delete.return_value = None450 # should return None451 assert self.backend.delete('1f3fab') is None452 self.backend.client.delete_item.assert_called_once_with(453 Key={u'id': {u'S': u'1f3fab'}},454 TableName='celery'455 )456 def test_backend_by_url(self, url='dynamodb://'):457 from celery.app import backends458 from celery.backends.dynamodb import DynamoDBBackend459 backend, url_ = backends.by_url(url, self.app.loader)460 assert backend is DynamoDBBackend461 assert url_ == url462 def test_backend_params_by_url(self):463 self.app.conf.result_backend = (464 'dynamodb://@us-east-1/celery_results'465 '?read=10'466 '&write=20'467 '&ttl_seconds=600'468 )469 assert self.backend.aws_region == 'us-east-1'470 assert self.backend.table_name == 'celery_results'471 assert self.backend.read_capacity_units == 10472 assert self.backend.write_capacity_units == 20473 assert self.backend.time_to_live_seconds == 600...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!