|
14 | 14 |
|
15 | 15 | import datetime |
16 | 16 | import os |
| 17 | +import string |
17 | 18 | import unittest |
18 | 19 |
|
19 | 20 | import requests |
@@ -465,6 +466,62 @@ def test_query_distinct_on(self): |
465 | 466 | self.assertEqual(entities[1]["name"], "Arya") |
466 | 467 |
|
467 | 468 |
|
| 469 | +class TestDatastoreQueryOffsets(TestDatastore): |
| 470 | + TOTAL_OBJECTS = 2500 |
| 471 | + NAMESPACE = "LargeCharacterEntity" |
| 472 | + KIND = "LargeCharacter" |
| 473 | + |
| 474 | + @classmethod |
| 475 | + def setUpClass(cls): |
| 476 | + cls.CLIENT = clone_client(Config.CLIENT) |
| 477 | + # Remove the namespace from the cloned client, since these |
| 478 | + # query tests rely on the entities to be already stored |
| 479 | + # cls.CLIENT.namespace = cls.NAMESPACE |
| 480 | + cls.CLIENT.namespace = None |
| 481 | + |
| 482 | + # Populating the datastore if necessary. |
| 483 | + populate_datastore.add_large_character_entities(client=cls.CLIENT) |
| 484 | + |
| 485 | + @classmethod |
| 486 | + def tearDownClass(cls): |
| 487 | + # In the emulator, destroy the query entities. |
| 488 | + if os.getenv(GCD_DATASET) is not None: |
| 489 | + # Use the client for this test instead of the global. |
| 490 | + clear_datastore.remove_all_entities(client=cls.CLIENT) |
| 491 | + |
| 492 | + def _base_query(self): |
| 493 | + # Use the client for this test instead of the global. |
| 494 | + return self.CLIENT.query(kind=self.KIND, namespace=self.NAMESPACE) |
| 495 | + |
| 496 | + def _verify(self, limit, offset, expected): |
| 497 | + # Query used for all tests |
| 498 | + page_query = self._base_query() |
| 499 | + page_query.add_filter("family", "=", "Stark") |
| 500 | + page_query.add_filter("alive", "=", False) |
| 501 | + |
| 502 | + iterator = page_query.fetch(limit=limit, offset=offset) |
| 503 | + entities = [e for e in iterator] |
| 504 | + self.assertEqual(len(entities), expected) |
| 505 | + |
| 506 | + def test_query_in_bounds_offsets(self): |
| 507 | + # Verify that with no offset there are the correct # of results |
| 508 | + self._verify(limit=None, offset=None, expected=self.TOTAL_OBJECTS) |
| 509 | + |
| 510 | + # Verify that with no limit there are results (offset provided)") |
| 511 | + self._verify(limit=None, offset=900, expected=self.TOTAL_OBJECTS - 900) |
| 512 | + |
| 513 | + # Offset beyond items larger Verify 200 items found") |
| 514 | + self._verify(limit=200, offset=1100, expected=200) |
| 515 | + |
| 516 | + def test_query_partially_out_of_bounds_offsets(self): |
| 517 | + # Offset within range, expect 50 despite larger limit") |
| 518 | + self._verify(limit=100, offset=self.TOTAL_OBJECTS - 50, expected=50) |
| 519 | + |
| 520 | + def test_query_out_of_bounds_offsets(self): |
| 521 | + # Offset beyond items larger Verify no items found") |
| 522 | + self._verify(limit=200, offset=self.TOTAL_OBJECTS + 1000, expected=0) |
| 523 | + |
| 524 | + |
468 | 525 | class TestDatastoreTransaction(TestDatastore): |
469 | 526 | def test_transaction_via_with_statement(self): |
470 | 527 | entity = datastore.Entity(key=Config.CLIENT.key("Company", "Google")) |
|
0 commit comments