@@ -26,6 +26,11 @@ def sample_data(collection):
26
26
for x in range (1 , 6 ):
27
27
collection .add ({"x" : x })
28
28
29
+ subcollection_doc = collection .document ("subcollection" )
30
+ subcollection_doc .set ({})
31
+ subcollection_doc .collection ("subcollection1" ).add ({})
32
+
33
+
29
34
# ===== AsyncQuery =====
30
35
31
36
async def _exercise_async_query (async_collection ):
@@ -103,3 +108,79 @@ def _test():
103
108
def test_firestore_async_aggregation_query_generators (async_collection , assert_trace_for_async_generator ):
104
109
async_aggregation_query = async_collection .select ("x" ).where (field_path = "x" , op_string = "<=" , value = 3 ).count ()
105
110
assert_trace_for_async_generator (async_aggregation_query .stream )
111
+
112
+
113
+ # ===== CollectionGroup =====
114
+
115
+
116
+ @pytest .fixture ()
117
+ def patch_partition_queries (monkeypatch , async_client , collection , sample_data ):
118
+ """
119
+ Partitioning is not implemented in the Firestore emulator.
120
+
121
+ Ordinarily this method would return a coroutine that returns an async_generator of Cursor objects.
122
+ Each Cursor must point at a valid document path. To test this, we can patch the RPC to return 1 Cursor
123
+ which is pointed at any document available. The get_partitions will take that and make 2 QueryPartition
124
+ objects out of it, which should be enough to ensure we can exercise the generator's tracing.
125
+ """
126
+ from google .cloud .firestore_v1 .types .document import Value
127
+ from google .cloud .firestore_v1 .types .query import Cursor
128
+
129
+ subcollection = collection .document ("subcollection" ).collection ("subcollection1" )
130
+ documents = [d for d in subcollection .list_documents ()]
131
+
132
+ async def mock_partition_query (* args , ** kwargs ):
133
+ async def _mock_partition_query ():
134
+ yield Cursor (before = False , values = [Value (reference_value = documents [0 ].path )])
135
+ return _mock_partition_query ()
136
+
137
+ monkeypatch .setattr (async_client ._firestore_api , "partition_query" , mock_partition_query )
138
+ yield
139
+
140
+
141
+ async def _exercise_async_collection_group (async_client , async_collection ):
142
+ async_collection_group = async_client .collection_group (async_collection .id )
143
+ assert len (await async_collection_group .get ())
144
+ assert len ([d async for d in async_collection_group .stream ()])
145
+
146
+ partitions = [p async for p in async_collection_group .get_partitions (1 )]
147
+ assert len (partitions ) == 2
148
+ documents = []
149
+ while partitions :
150
+ documents .extend (await partitions .pop ().query ().get ())
151
+ assert len (documents ) == 6
152
+
153
+
154
+ def test_firestore_async_collection_group (loop , async_client , async_collection , patch_partition_queries ):
155
+ _test_scoped_metrics = [
156
+ ("Datastore/statement/Firestore/%s/get" % async_collection .id , 3 ),
157
+ ("Datastore/statement/Firestore/%s/stream" % async_collection .id , 1 ),
158
+ ("Datastore/statement/Firestore/%s/get_partitions" % async_collection .id , 1 ),
159
+ ]
160
+
161
+ _test_rollup_metrics = [
162
+ ("Datastore/operation/Firestore/get" , 3 ),
163
+ ("Datastore/operation/Firestore/stream" , 1 ),
164
+ ("Datastore/operation/Firestore/get_partitions" , 1 ),
165
+ ("Datastore/all" , 5 ),
166
+ ("Datastore/allOther" , 5 ),
167
+ ]
168
+
169
+ @validate_database_duration ()
170
+ @validate_transaction_metrics (
171
+ "test_firestore_async_collection_group" ,
172
+ scoped_metrics = _test_scoped_metrics ,
173
+ rollup_metrics = _test_rollup_metrics ,
174
+ background_task = True ,
175
+ )
176
+ @background_task (name = "test_firestore_async_collection_group" )
177
+ def _test ():
178
+ loop .run_until_complete (_exercise_async_collection_group (async_client , async_collection ))
179
+
180
+ _test ()
181
+
182
+
183
+ @background_task ()
184
+ def test_firestore_async_collection_group_generators (async_client , async_collection , assert_trace_for_async_generator , patch_partition_queries ):
185
+ async_collection_group = async_client .collection_group (async_collection .id )
186
+ assert_trace_for_async_generator (async_collection_group .get_partitions , 1 )
0 commit comments