From ebe0815a72d72e8eb3af477b6878d23486fd4f07 Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Mon, 24 Aug 2020 14:40:52 -0700 Subject: [PATCH 01/12] fixed bug in querying by page using continuation token --- .../base_execution_context.py | 2 +- sdk/cosmos/azure-cosmos/test/test_query.py | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py index c125e870b3a4..758553dd1ae0 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py @@ -44,7 +44,7 @@ def __init__(self, client, options): self._options = options self._is_change_feed = "changeFeed" in options and options["changeFeed"] is True self._continuation = None - if "continuation" in options and self._is_change_feed: + if "continuation" in options: self._continuation = options["continuation"] self._has_started = False self._has_finished = False diff --git a/sdk/cosmos/azure-cosmos/test/test_query.py b/sdk/cosmos/azure-cosmos/test/test_query.py index 59204ef863ea..cec9b2bdf0d0 100644 --- a/sdk/cosmos/azure-cosmos/test/test_query.py +++ b/sdk/cosmos/azure-cosmos/test/test_query.py @@ -522,6 +522,30 @@ def test_distinct_on_different_types_and_field_orders(self): _QueryExecutionContextBase.__next__ = self.OriginalExecuteFunction _QueryExecutionContextBase.next = self.OriginalExecuteFunction + def test_paging_with_continuation_token(self): + created_collection = self.config.create_multi_partition_collection_with_custom_pk_if_not_exist(self.client) + + document_definition = {'pk': 'pk', 'id': '1'} + created_collection.create_item(body=document_definition) + document_definition = {'pk': 'pk', 'id': '2'} + created_collection.create_item(body=document_definition) + + query = 'SELECT * from c' + query_iterable = created_collection.query_items( + query=query, + partition_key='pk', + max_item_count=1 + ) + pager = query_iterable.by_page() + pager.next() + token = pager.continuation_token + second_page = list(pager.next())[0] + + pager = query_iterable.by_page(token) + second_page_fetched_with_continuation_token = list(pager.next())[0] + + self.assertEqual(second_page['id'], second_page_fetched_with_continuation_token['id']) + def _validate_distinct_on_different_types_and_field_orders(self, collection, query, expected_results, get_mock_result): self.count = 0 self.get_mock_result = get_mock_result From 205475d3bdf8da36df702477263b544aa06afeb9 Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Mon, 24 Aug 2020 15:07:09 -0700 Subject: [PATCH 02/12] updated changelog --- sdk/cosmos/azure-cosmos/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdk/cosmos/azure-cosmos/CHANGELOG.md b/sdk/cosmos/azure-cosmos/CHANGELOG.md index e2940d239b72..0b0f25909a76 100644 --- a/sdk/cosmos/azure-cosmos/CHANGELOG.md +++ b/sdk/cosmos/azure-cosmos/CHANGELOG.md @@ -1,3 +1,7 @@ +**Bug fixes** +- Fixed bug where continuation token is not honored when query_iterable is used to get results by page. Issue #13265. + + ## 4.1.0 (2020-08-10) - Added deprecation warning for "lazy" indexing mode. The backend no longer allows creating containers with this mode and will set them to consistent instead. From 0c964948ccfaab501fdd396b6515f4a90c73a216 Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Mon, 24 Aug 2020 16:39:43 -0700 Subject: [PATCH 03/12] modified changelog --- sdk/cosmos/azure-cosmos/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/cosmos/azure-cosmos/CHANGELOG.md b/sdk/cosmos/azure-cosmos/CHANGELOG.md index 0b0f25909a76..90015159104c 100644 --- a/sdk/cosmos/azure-cosmos/CHANGELOG.md +++ b/sdk/cosmos/azure-cosmos/CHANGELOG.md @@ -1,3 +1,5 @@ +## 4.1.1 (unreleased) + **Bug fixes** - Fixed bug where continuation token is not honored when query_iterable is used to get results by page. Issue #13265. From 98d1776af32684350234d054b68714d0913462ea Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Wed, 26 Aug 2020 07:25:27 -0700 Subject: [PATCH 04/12] added support from single partition query continuation tokens --- .../base_execution_context.py | 18 +++++++++++++----- sdk/cosmos/azure-cosmos/test/test_query.py | 12 ++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py index 758553dd1ae0..8d5bd2c53fdf 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py @@ -26,6 +26,7 @@ from collections import deque from .. import _retry_utility from .. import http_constants +import copy # pylint: disable=protected-access @@ -43,13 +44,19 @@ def __init__(self, client, options): self._client = client self._options = options self._is_change_feed = "changeFeed" in options and options["changeFeed"] is True - self._continuation = None - if "continuation" in options: - self._continuation = options["continuation"] + self._continuation = self._get_initial_continuation() self._has_started = False self._has_finished = False self._buffer = deque() + def _get_initial_continuation(self): + if "continuation" in self._options: + if "enableCrossPartitionQuery" in self._options: + raise AttributeError("continuation tokens are not supported for cross-partition queries.") + else: + return self._options["continuation"] + return None + def _has_more_pages(self): return not self._has_started or self._continuation @@ -112,8 +119,9 @@ def _fetch_items_helper_no_retries(self, fetch_function): while self._continuation or not self._has_started: if not self._has_started: self._has_started = True - self._options["continuation"] = self._continuation - (fetched_items, response_headers) = fetch_function(self._options) + new_options = copy.deepcopy(self._options) + new_options["continuation"] = self._continuation + (fetched_items, response_headers) = fetch_function(new_options) continuation_key = http_constants.HttpHeaders.Continuation # Use Etag as continuation token for change feed queries. if self._is_change_feed: diff --git a/sdk/cosmos/azure-cosmos/test/test_query.py b/sdk/cosmos/azure-cosmos/test/test_query.py index cec9b2bdf0d0..ca28e70a81fc 100644 --- a/sdk/cosmos/azure-cosmos/test/test_query.py +++ b/sdk/cosmos/azure-cosmos/test/test_query.py @@ -546,6 +546,18 @@ def test_paging_with_continuation_token(self): self.assertEqual(second_page['id'], second_page_fetched_with_continuation_token['id']) + def test_cross_partition_query_with_continuation_token_fails(self): + created_collection = self.config.create_multi_partition_collection_with_custom_pk_if_not_exist(self.client) + query = 'SELECT * from c' + query_iterable = created_collection.query_items( + query=query, + enable_cross_partition_query=True, + max_item_count=1, + ) + + with self.assertRaises(AttributeError): + pager = query_iterable.by_page("fake_continuation_token") + def _validate_distinct_on_different_types_and_field_orders(self, collection, query, expected_results, get_mock_result): self.count = 0 self.get_mock_result = get_mock_result From a1414701e4a82d3260f1cc0b7a3da0ed8c4db278 Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Wed, 26 Aug 2020 11:43:34 -0700 Subject: [PATCH 05/12] fixed linting error --- .../cosmos/_execution_context/base_execution_context.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py index 8d5bd2c53fdf..93f1e514c666 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py @@ -24,9 +24,9 @@ """ from collections import deque +import copy from .. import _retry_utility from .. import http_constants -import copy # pylint: disable=protected-access @@ -53,8 +53,7 @@ def _get_initial_continuation(self): if "continuation" in self._options: if "enableCrossPartitionQuery" in self._options: raise AttributeError("continuation tokens are not supported for cross-partition queries.") - else: - return self._options["continuation"] + return self._options["continuation"] return None def _has_more_pages(self): From a0973da8e0dbfa31908f6f0874049c9664f5d5ff Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Wed, 26 Aug 2020 16:53:43 -0700 Subject: [PATCH 06/12] addressed PR comments --- .../azure/cosmos/_execution_context/base_execution_context.py | 2 +- sdk/cosmos/azure-cosmos/test/test_query.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py b/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py index 93f1e514c666..3897e5a8a6b1 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py @@ -52,7 +52,7 @@ def __init__(self, client, options): def _get_initial_continuation(self): if "continuation" in self._options: if "enableCrossPartitionQuery" in self._options: - raise AttributeError("continuation tokens are not supported for cross-partition queries.") + raise ValueError("continuation tokens are not supported for cross-partition queries.") return self._options["continuation"] return None diff --git a/sdk/cosmos/azure-cosmos/test/test_query.py b/sdk/cosmos/azure-cosmos/test/test_query.py index ca28e70a81fc..44d59975c46c 100644 --- a/sdk/cosmos/azure-cosmos/test/test_query.py +++ b/sdk/cosmos/azure-cosmos/test/test_query.py @@ -555,7 +555,7 @@ def test_cross_partition_query_with_continuation_token_fails(self): max_item_count=1, ) - with self.assertRaises(AttributeError): + with self.assertRaises(ValueError): pager = query_iterable.by_page("fake_continuation_token") def _validate_distinct_on_different_types_and_field_orders(self, collection, query, expected_results, get_mock_result): From 62b612b51ffa4ecef8575a9f271ee012d00090bd Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Thu, 17 Sep 2020 17:16:52 -0700 Subject: [PATCH 07/12] Fixed resource token issues - Modified existing tests --- sdk/cosmos/azure-cosmos/azure/cosmos/auth.py | 13 +- sdk/cosmos/azure-cosmos/test/test_crud.py | 152 ++++++++----------- 2 files changed, 74 insertions(+), 91 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py b/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py index aa96ce946b7f..23d68256776e 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py @@ -27,6 +27,7 @@ import hmac import six +import six.moves.urllib.parse as url_parse from . import http_constants @@ -118,6 +119,7 @@ def __GetAuthorizationTokenUsingResourceTokens(resource_tokens, path, resource_i # For database account access(through GetDatabaseAccount API), path and # resource_id_or_fullname are '', so in this case we return the first token to be # used for creating the auth header as the service will accept any token in this case + path = url_parse.unquote(path) if not path and not resource_id_or_fullname: return next(six.itervalues(resource_tokens)) @@ -126,7 +128,7 @@ def __GetAuthorizationTokenUsingResourceTokens(resource_tokens, path, resource_i path_parts = [] if path: - path_parts = path.split("/") + path_parts = [item for item in path.split("/") if item] resource_types = [ "dbs", "colls", @@ -140,9 +142,12 @@ def __GetAuthorizationTokenUsingResourceTokens(resource_tokens, path, resource_i "conflicts", "offers", ] + # Get the last resource id or resource name from the path and get it's token from resource_tokens - for one_part in reversed(path_parts): - if not one_part in resource_types and one_part in resource_tokens: - return resource_tokens[one_part] + for i in range(len(path_parts), 1, -1): + segment = path_parts[i-1] + sub_path = "/".join(path_parts[:i]) + if not segment in resource_types and sub_path in resource_tokens: + return resource_tokens[sub_path] return None diff --git a/sdk/cosmos/azure-cosmos/test/test_crud.py b/sdk/cosmos/azure-cosmos/test/test_crud.py index 0a1a75cfebc9..e0df980310f5 100644 --- a/sdk/cosmos/azure-cosmos/test/test_crud.py +++ b/sdk/cosmos/azure-cosmos/test/test_crud.py @@ -567,8 +567,8 @@ def test_partitioned_collection_permissions(self): resource_tokens = {} # storing the resource tokens based on Resource IDs - resource_tokens[urllib.quote(all_collection.id)] = (all_permission.properties['_token']) - resource_tokens[urllib.quote(read_collection.id)] = (read_permission.properties['_token']) + resource_tokens["dbs/" + created_db.id + "/colls/" + all_collection.id] = (all_permission.properties['_token']) + resource_tokens["dbs/" + created_db.id + "/colls/" + read_collection.id] = (read_permission.properties['_token']) restricted_client = cosmos_client.CosmosClient( CRUDTests.host, resource_tokens, "Session", connection_policy=CRUDTests.connectionPolicy) @@ -1302,71 +1302,48 @@ def __SetupEntities(client): """ # create database db = self.databaseForTest - # create collection1 - collection1 = db.create_container( + # create collection + collection = db.create_container( id='test_authorization' + str(uuid.uuid4()), partition_key=PartitionKey(path='/id', kind='Hash') ) # create document1 - document1 = collection1.create_item( - body={'id': 'coll1doc1', + document = collection.create_item( + body={'id': 'doc1', 'spam': 'eggs', 'key': 'value'}, ) - # create document 2 - document2 = collection1.create_item( - body={'id': 'coll1doc2', 'spam': 'eggs2', 'key': 'value2'} - ) - # create collection 2 - collection2 = db.create_container( - id='test_authorization2' + str(uuid.uuid4()), - partition_key=PartitionKey(path='/id', kind='Hash') - ) - # create user1 - user1 = db.create_user(body={'id': 'user1'}) - collection1_properties = collection1.read() + # create user + user = db.create_user(body={'id': 'user'}) + + # create permission for collection permission = { - 'id': 'permission On Coll1', + 'id': 'permission On Coll', 'permissionMode': documents.PermissionMode.Read, - 'resource': collection1_properties['_self'] - } - # create permission for collection1 - permission_on_coll1 = user1.create_permission(body=permission) - self.assertIsNotNone(permission_on_coll1.properties['_token'], - 'permission token is invalid') - permission = { - 'id': 'permission On Doc1', - 'permissionMode': documents.PermissionMode.All, - 'resource': document2['_self'] + 'resource': "dbs/" + db.id + "/colls/" + collection.id } - # create permission for document 2 - permission_on_doc2 = user1.create_permission(body=permission) - self.assertIsNotNone(permission_on_doc2.properties['_token'], + permission_on_coll = user.create_permission(body=permission) + self.assertIsNotNone(permission_on_coll.properties['_token'], 'permission token is invalid') - # create user 2 - user2 = db.create_user(body={'id': 'user2'}) - collection2_properties = collection2.read() + + # create permission for document permission = { - 'id': 'permission On coll2', + 'id': 'permission On Doc', 'permissionMode': documents.PermissionMode.All, - 'resource': collection2_properties['_self'] + 'resource': "dbs/" + db.id + "/colls/" + collection.id + "/docs/" + document["id"] } - # create permission on collection 2 - permission_on_coll2 = user2.create_permission(body=permission) - self.assertIsNotNone(permission_on_coll2.properties['_token'], + permission_on_doc = user.create_permission(body=permission) + self.assertIsNotNone(permission_on_doc.properties['_token'], 'permission token is invalid') + entities = { 'db': db, - 'coll1': collection1, - 'coll2': collection2, - 'doc1': document1, - 'doc2': document2, - 'user1': user1, - 'user2': user2, - 'permissionOnColl1': permission_on_coll1, - 'permissionOnDoc2': permission_on_doc2, - 'permissionOnColl2': permission_on_coll2 + 'coll': collection, + 'doc': document, + 'user': user, + 'permissionOnColl': permission_on_coll, + 'permissionOnDoc': permission_on_doc, } return entities @@ -1382,60 +1359,61 @@ def __SetupEntities(client): connection_policy=CRUDTests.connectionPolicy) # setup entities entities = __SetupEntities(client) - resource_tokens = {} - resource_tokens[entities['coll1'].id] = ( - entities['permissionOnColl1'].properties['_token']) - resource_tokens[entities['doc1']['id']]= ( - entities['permissionOnColl1'].properties['_token']) - col1_client = cosmos_client.CosmosClient( + resource_tokens = {"dbs/" + entities['db'].id + "/colls/" + entities['coll'].id: + entities['permissionOnColl'].properties['_token']} + col_client = cosmos_client.CosmosClient( CRUDTests.host, resource_tokens,"Session", connection_policy=CRUDTests.connectionPolicy) db = entities['db'] old_client_connection = db.client_connection - db.client_connection = col1_client.client_connection - # 1. Success-- Use Col1 Permission to Read - success_coll1 = db.get_container_client(container=entities['coll1']) - # 2. Failure-- Use Col1 Permission to delete + db.client_connection = col_client.client_connection + # 1. Success-- Use Col Permission to Read + success_coll = db.get_container_client(container=entities['coll']) + # 2. Failure-- Use Col Permission to delete self.__AssertHTTPFailureWithStatus(StatusCodes.FORBIDDEN, db.delete_container, - success_coll1) - # 3. Success-- Use Col1 Permission to Read All Docs - success_documents = list(success_coll1.read_all_items()) + success_coll) + # 3. Success-- Use Col Permission to Read All Docs + success_documents = list(success_coll.read_all_items()) self.assertTrue(success_documents != None, 'error reading documents') self.assertEqual(len(success_documents), - 2, - 'Expected 2 Documents to be succesfully read') - # 4. Success-- Use Col1 Permission to Read Col1Doc1 - success_doc = success_coll1.read_item( - item=entities['doc1']['id'], - partition_key=entities['doc1']['id'] + 1, + 'Expected 1 Document to be succesfully read') + # 4. Success-- Use Col Permission to Read Doc + + docId = entities['doc']['id'] + success_doc = success_coll.read_item( + item=docId, + partition_key=docId ) self.assertTrue(success_doc != None, 'error reading document') self.assertEqual( success_doc['id'], - entities['doc1']['id'], + entities['doc']['id'], 'Expected to read children using parent permissions') - col2_client = cosmos_client.CosmosClient( - CRUDTests.host, - [entities['permissionOnColl2'].properties], - "Session", - connection_policy=CRUDTests.connectionPolicy) - doc = { - 'CustomProperty1': 'BBBBBB', - 'customProperty2': 1000, - 'id': entities['doc2']['id'] - } - entities['coll2'].client_connection = col2_client.client_connection - success_doc = entities['coll2'].create_item(body=doc) - self.assertTrue(success_doc != None, 'error creating document') - self.assertEqual(success_doc['CustomProperty1'], - doc['CustomProperty1'], - 'document should have been created successfully') + + #5. Failure-- Use Col Permission to Delete Doc + self.__AssertHTTPFailureWithStatus(StatusCodes.FORBIDDEN, + success_coll.delete_item, + docId, docId) + + resource_tokens = {"dbs/" + entities['db'].id + "/colls/" + entities['coll'].id + "/docs/" + docId : + entities['permissionOnDoc'].properties['_token']} + + doc_client = cosmos_client.CosmosClient( + CRUDTests.host, resource_tokens,"Session", connection_policy=CRUDTests.connectionPolicy) + + #6. Success-- Use Doc permission to read doc + read_doc = doc_client.get_database_client(db.id).get_container_client(success_coll.id).read_item(docId, docId) + self.assertEqual(read_doc["id"], docId) + + #6. Success-- Use Doc permission to delete doc + doc_client.get_database_client(db.id).get_container_client(success_coll.id).delete_item(docId, docId) + self.assertEqual(read_doc["id"], docId) db.client_connection = old_client_connection - db.delete_container(entities['coll1']) - db.delete_container(entities['coll2']) + db.delete_container(entities['coll']) def test_trigger_crud(self): # create database From 89582ce749e8b12ec9c8f96280d70a2005386edb Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Thu, 17 Sep 2020 17:43:22 -0700 Subject: [PATCH 08/12] fixed linting error --- sdk/cosmos/azure-cosmos/azure/cosmos/auth.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py b/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py index 23d68256776e..98821ba17b37 100644 --- a/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py +++ b/sdk/cosmos/azure-cosmos/azure/cosmos/auth.py @@ -27,7 +27,6 @@ import hmac import six -import six.moves.urllib.parse as url_parse from . import http_constants @@ -119,7 +118,7 @@ def __GetAuthorizationTokenUsingResourceTokens(resource_tokens, path, resource_i # For database account access(through GetDatabaseAccount API), path and # resource_id_or_fullname are '', so in this case we return the first token to be # used for creating the auth header as the service will accept any token in this case - path = url_parse.unquote(path) + path = six.moves.urllib.parse.unquote(path) if not path and not resource_id_or_fullname: return next(six.itervalues(resource_tokens)) From ac9f072a5db3350bd050e1e14e389c7a1d2e9e70 Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Thu, 17 Sep 2020 19:11:18 -0700 Subject: [PATCH 09/12] sample commit --- sdk/cosmos/azure-cosmos/test/test_query.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/cosmos/azure-cosmos/test/test_query.py b/sdk/cosmos/azure-cosmos/test/test_query.py index 44d59975c46c..755d8a8a6cc6 100644 --- a/sdk/cosmos/azure-cosmos/test/test_query.py +++ b/sdk/cosmos/azure-cosmos/test/test_query.py @@ -47,6 +47,7 @@ def test_first_and_last_slashes_trimmed_for_query_string (self): iter_list = list(query_iterable) self.assertEqual(iter_list[0]['id'], 'myId') + def test_query_change_feed(self): created_collection = self.config.create_multi_partition_collection_with_custom_pk_if_not_exist(self.client) # The test targets partition #3 From ac66ecfe1cd2e9a15437b631ba94aa8ada51cbd8 Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Thu, 17 Sep 2020 19:11:37 -0700 Subject: [PATCH 10/12] commit reverted --- sdk/cosmos/azure-cosmos/test/test_query.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/cosmos/azure-cosmos/test/test_query.py b/sdk/cosmos/azure-cosmos/test/test_query.py index 755d8a8a6cc6..44d59975c46c 100644 --- a/sdk/cosmos/azure-cosmos/test/test_query.py +++ b/sdk/cosmos/azure-cosmos/test/test_query.py @@ -47,7 +47,6 @@ def test_first_and_last_slashes_trimmed_for_query_string (self): iter_list = list(query_iterable) self.assertEqual(iter_list[0]['id'], 'myId') - def test_query_change_feed(self): created_collection = self.config.create_multi_partition_collection_with_custom_pk_if_not_exist(self.client) # The test targets partition #3 From 6b42b9ea6227e43bf8d3e214c546dc82764c889b Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Thu, 17 Sep 2020 20:51:53 -0700 Subject: [PATCH 11/12] fixed failing tests --- sdk/cosmos/azure-cosmos/test/test_crud.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/cosmos/azure-cosmos/test/test_crud.py b/sdk/cosmos/azure-cosmos/test/test_crud.py index e0df980310f5..ab9e89d9522b 100644 --- a/sdk/cosmos/azure-cosmos/test/test_crud.py +++ b/sdk/cosmos/azure-cosmos/test/test_crud.py @@ -531,21 +531,21 @@ def test_partitioned_collection_document_crud_and_query(self): def test_partitioned_collection_permissions(self): created_db = self.databaseForTest - collection_id = 'test_partitioned_collection_permissions all collection' + collection_id = 'test_partitioned_collection_permissions all collection' + str(uuid.uuid4()) all_collection = created_db.create_container( id=collection_id, partition_key=PartitionKey(path='/key', kind=documents.PartitionKind.Hash) ) - collection_id = 'test_partitioned_collection_permissions read collection' + collection_id = 'test_partitioned_collection_permissions read collection' + str(uuid.uuid4()) read_collection = created_db.create_container( id=collection_id, partition_key=PartitionKey(path='/key', kind=documents.PartitionKind.Hash) ) - user = created_db.create_user(body={'id': 'user'}) + user = created_db.create_user(body={'id': 'user' + str(uuid.uuid4())}) permission_definition = { 'id': 'all permission', @@ -1315,7 +1315,7 @@ def __SetupEntities(client): ) # create user - user = db.create_user(body={'id': 'user'}) + user = db.create_user(body={'id': 'user' + str(uuid.uuid4())}) # create permission for collection permission = { From b8f58bab9d80d6ba50e0cccba2e2916f9ff672c5 Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Fri, 18 Sep 2020 13:25:13 -0700 Subject: [PATCH 12/12] updated changelog --- sdk/cosmos/azure-cosmos/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/cosmos/azure-cosmos/CHANGELOG.md b/sdk/cosmos/azure-cosmos/CHANGELOG.md index 90015159104c..ad2ca82db459 100644 --- a/sdk/cosmos/azure-cosmos/CHANGELOG.md +++ b/sdk/cosmos/azure-cosmos/CHANGELOG.md @@ -2,6 +2,7 @@ **Bug fixes** - Fixed bug where continuation token is not honored when query_iterable is used to get results by page. Issue #13265. +- Fixed bug where resource tokens not being honored for document reads and deletes. Issue #13634. ## 4.1.0 (2020-08-10)