From a4a3b2fe4306549eff60be5b00bbb617274bfaf5 Mon Sep 17 00:00:00 2001 From: Nadav Har'El Date: Tue, 14 May 2019 19:28:15 +0300 Subject: [PATCH] alternator-test: test for sort order of items in a single partition Although different partitions are returned by a Scan in (seemingly) random order, items in a single partition need to be returned sorted by their sort key. This adds a test to verify this. This patch adds to the filled_test_table fixture, which until now had just one item in each partition, another partition (with the key "long") with 164 additional items. The test_scan_sort_order_string test then scans this table, and verifies that the items are really returned in sorted order. The sort order is, of course, string order. So we have the first item with sort key "1", then "10", then "100", then "101", "102", etc. When we implement numeric keys we'll need to add a version of this test which uses a numeric clustering key and verifies the sort order is numeric. Signed-off-by: Nadav Har'El --- alternator-test/conftest.py | 14 +++++++++++--- alternator-test/test_scan.py | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/alternator-test/conftest.py b/alternator-test/conftest.py index 54ee95462b..5b822ce543 100644 --- a/alternator-test/conftest.py +++ b/alternator-test/conftest.py @@ -104,9 +104,11 @@ def test_2_tables(dynamodb): # "filled_test_table" fixture: Create a temporary table to be used in tests # that involve reading data - GetItem, Scan, etc. The table is filled with -# 164 elements - each consisting of a partition key, clustering key -# and two string attributes. This table is supposed to be read from, -# not updated nor overwritten. +# 328 items - each consisting of a partition key, clustering key and two +# string attributes. 164 of the items are in a single partition (with the +# partition key 'long') and the 164 other items are each in a separate +# partition. +# This table is supposed to be read from, not updated nor overwritten. # This fixture returns both a table object and the description of all items # inserted into it. @pytest.fixture(scope="session") @@ -126,6 +128,12 @@ def filled_test_table(dynamodb): 'attribute': "x" * 7, 'another': "y" * 16 } for i in range(count)] + items = items + [{ + 'p': 'long', + 'c': str(i), + 'attribute': "x" * 7, + 'another': "y" * 16 + } for i in range(count)] for item in items: # TODO: eventually, when Alternator supports batch operations, diff --git a/alternator-test/test_scan.py b/alternator-test/test_scan.py index d012104a94..c3f8b2269b 100644 --- a/alternator-test/test_scan.py +++ b/alternator-test/test_scan.py @@ -47,3 +47,26 @@ def test_scan_with_paginator(dynamodb, filled_test_table): assert len(items) == len(got_items) assert set_of_frozen_elements(items) == set_of_frozen_elements(got_items) + +# Although partitions are scanned in seemingly-random order, inside a +# partition items must be returned by Scan sorted in sort-key order. +# This test verifies this, for string sort key. We'll need separate +# tests for the other sort-key types (number and binary) +def test_scan_sort_order_string(filled_test_table): + test_table, items = filled_test_table + pos = None + got_items = [] + while True: + response = test_table.scan(ExclusiveStartKey=pos) if pos else test_table.scan() + pos = response.get('LastEvaluatedKey', None) + got_items += response['Items'] + if not pos: + break + assert len(items) == len(got_items) + # Extract just the sort key ("c") from the partition "long" + items_long = [x['c'] for x in items if x['p'] == 'long'] + got_items_long = [x['c'] for x in got_items if x['p'] == 'long'] + # Verify that got_items_long are already sorted (in string order) + assert sorted(got_items_long) == got_items_long + # Verify that got_items_long are a sorted version of the expected items_long + assert sorted(items_long) == got_items_long