| Index: third_party/boto/tests/unit/dynamodb2/test_table.py
|
| ===================================================================
|
| --- third_party/boto/tests/unit/dynamodb2/test_table.py (revision 33376)
|
| +++ third_party/boto/tests/unit/dynamodb2/test_table.py (working copy)
|
| @@ -1,5 +1,5 @@
|
| import mock
|
| -import unittest
|
| +from tests.unit import unittest
|
| from boto.dynamodb2 import exceptions
|
| from boto.dynamodb2.fields import (HashKey, RangeKey,
|
| AllIndex, KeysOnlyIndex, IncludeIndex,
|
| @@ -9,7 +9,7 @@
|
| from boto.dynamodb2.layer1 import DynamoDBConnection
|
| from boto.dynamodb2.results import ResultSet, BatchGetResultSet
|
| from boto.dynamodb2.table import Table
|
| -from boto.dynamodb2.types import (STRING, NUMBER,
|
| +from boto.dynamodb2.types import (STRING, NUMBER, BINARY,
|
| FILTER_OPERATORS, QUERY_OPERATORS)
|
| from boto.exception import JSONResponseError
|
|
|
| @@ -17,7 +17,6 @@
|
| FakeDynamoDBConnection = mock.create_autospec(DynamoDBConnection)
|
|
|
|
|
| -
|
| class SchemaFieldsTestCase(unittest.TestCase):
|
| def test_hash_key(self):
|
| hash_key = HashKey('hello')
|
| @@ -299,7 +298,44 @@
|
| }
|
| })
|
|
|
| + def test_global_include_index_throughput(self):
|
| + include_index = GlobalIncludeIndex('IncludeKeys', parts=[
|
| + HashKey('username'),
|
| + RangeKey('date_joined')
|
| + ], includes=[
|
| + 'gender',
|
| + 'friend_count'
|
| + ], throughput={
|
| + 'read': 10,
|
| + 'write': 8
|
| + })
|
|
|
| + self.assertEqual(include_index.schema(), {
|
| + 'IndexName': 'IncludeKeys',
|
| + 'KeySchema': [
|
| + {
|
| + 'AttributeName': 'username',
|
| + 'KeyType': 'HASH'
|
| + },
|
| + {
|
| + 'AttributeName': 'date_joined',
|
| + 'KeyType': 'RANGE'
|
| + }
|
| + ],
|
| + 'Projection': {
|
| + 'ProjectionType': 'INCLUDE',
|
| + 'NonKeyAttributes': [
|
| + 'gender',
|
| + 'friend_count',
|
| + ]
|
| + },
|
| + 'ProvisionedThroughput': {
|
| + 'ReadCapacityUnits': 10,
|
| + 'WriteCapacityUnits': 8
|
| + }
|
| + })
|
| +
|
| +
|
| class ItemTestCase(unittest.TestCase):
|
| def setUp(self):
|
| super(ItemTestCase, self).setUp()
|
| @@ -821,11 +857,33 @@
|
| def setUp(self):
|
| super(ResultSetTestCase, self).setUp()
|
| self.results = ResultSet()
|
| - self.results.to_call(fake_results, 'john', greeting='Hello', limit=20)
|
| + self.result_function = mock.MagicMock(side_effect=fake_results)
|
| + self.results.to_call(self.result_function, 'john', greeting='Hello', limit=20)
|
|
|
| def test_first_key(self):
|
| self.assertEqual(self.results.first_key, 'exclusive_start_key')
|
|
|
| + def test_max_page_size_fetch_more(self):
|
| + self.results = ResultSet(max_page_size=10)
|
| + self.results.to_call(self.result_function, 'john', greeting='Hello')
|
| + self.results.fetch_more()
|
| + self.result_function.assert_called_with('john', greeting='Hello', limit=10)
|
| + self.result_function.reset_mock()
|
| +
|
| + def test_max_page_size_and_smaller_limit_fetch_more(self):
|
| + self.results = ResultSet(max_page_size=10)
|
| + self.results.to_call(self.result_function, 'john', greeting='Hello', limit=5)
|
| + self.results.fetch_more()
|
| + self.result_function.assert_called_with('john', greeting='Hello', limit=5)
|
| + self.result_function.reset_mock()
|
| +
|
| + def test_max_page_size_and_bigger_limit_fetch_more(self):
|
| + self.results = ResultSet(max_page_size=10)
|
| + self.results.to_call(self.result_function, 'john', greeting='Hello', limit=15)
|
| + self.results.fetch_more()
|
| + self.result_function.assert_called_with('john', greeting='Hello', limit=10)
|
| + self.result_function.reset_mock()
|
| +
|
| def test_fetch_more(self):
|
| # First "page".
|
| self.results.fetch_more()
|
| @@ -837,6 +895,9 @@
|
| 'Hello john #4',
|
| ])
|
|
|
| + self.result_function.assert_called_with('john', greeting='Hello', limit=20)
|
| + self.result_function.reset_mock()
|
| +
|
| # Fake in a last key.
|
| self.results._last_key_seen = 4
|
| # Second "page".
|
| @@ -849,6 +910,9 @@
|
| 'Hello john #9',
|
| ])
|
|
|
| + self.result_function.assert_called_with('john', greeting='Hello', limit=20, exclusive_start_key=4)
|
| + self.result_function.reset_mock()
|
| +
|
| # Fake in a last key.
|
| self.results._last_key_seen = 9
|
| # Last "page".
|
| @@ -1090,7 +1154,17 @@
|
| "KeyType": "RANGE"
|
| }
|
| ]
|
| - schema_1 = self.users._introspect_schema(raw_schema_1)
|
| + raw_attributes_1 = [
|
| + {
|
| + 'AttributeName': 'username',
|
| + 'AttributeType': 'S'
|
| + },
|
| + {
|
| + 'AttributeName': 'date_joined',
|
| + 'AttributeType': 'S'
|
| + },
|
| + ]
|
| + schema_1 = self.users._introspect_schema(raw_schema_1, raw_attributes_1)
|
| self.assertEqual(len(schema_1), 2)
|
| self.assertTrue(isinstance(schema_1[0], HashKey))
|
| self.assertEqual(schema_1[0].name, 'username')
|
| @@ -1103,12 +1177,49 @@
|
| "KeyType": "BTREE"
|
| },
|
| ]
|
| + raw_attributes_2 = [
|
| + {
|
| + 'AttributeName': 'username',
|
| + 'AttributeType': 'S'
|
| + },
|
| + ]
|
| self.assertRaises(
|
| exceptions.UnknownSchemaFieldError,
|
| self.users._introspect_schema,
|
| - raw_schema_2
|
| + raw_schema_2,
|
| + raw_attributes_2
|
| )
|
|
|
| + # Test a complex schema & ensure the types come back correctly.
|
| + raw_schema_3 = [
|
| + {
|
| + "AttributeName": "user_id",
|
| + "KeyType": "HASH"
|
| + },
|
| + {
|
| + "AttributeName": "junk",
|
| + "KeyType": "RANGE"
|
| + }
|
| + ]
|
| + raw_attributes_3 = [
|
| + {
|
| + 'AttributeName': 'user_id',
|
| + 'AttributeType': 'N'
|
| + },
|
| + {
|
| + 'AttributeName': 'junk',
|
| + 'AttributeType': 'B'
|
| + },
|
| + ]
|
| + schema_3 = self.users._introspect_schema(raw_schema_3, raw_attributes_3)
|
| + self.assertEqual(len(schema_3), 2)
|
| + self.assertTrue(isinstance(schema_3[0], HashKey))
|
| + self.assertEqual(schema_3[0].name, 'user_id')
|
| + self.assertEqual(schema_3[0].data_type, NUMBER)
|
| + self.assertTrue(isinstance(schema_3[1], RangeKey))
|
| + self.assertEqual(schema_3[1].name, 'junk')
|
| + self.assertEqual(schema_3[1].data_type, BINARY)
|
| +
|
| def test__introspect_indexes(self):
|
| raw_indexes_1 = [
|
| {
|
| @@ -1596,7 +1707,6 @@
|
| username= 'johndoe',
|
| date_joined= 1366056668)
|
|
|
| -
|
| def test_put_item(self):
|
| with mock.patch.object(
|
| self.users.connection,
|
| @@ -1664,8 +1774,41 @@
|
| 'date_joined': {
|
| 'N': '23456'
|
| }
|
| - })
|
| + }, expected=None, conditional_operator=None)
|
|
|
| + def test_delete_item_conditionally(self):
|
| + with mock.patch.object(
|
| + self.users.connection,
|
| + 'delete_item',
|
| + return_value={}) as mock_delete_item:
|
| + self.assertTrue(self.users.delete_item(expected={'balance__eq': 0},
|
| + username='johndoe', date_joined=23456))
|
| +
|
| + mock_delete_item.assert_called_once_with('users', {
|
| + 'username': {
|
| + 'S': 'johndoe'
|
| + },
|
| + 'date_joined': {
|
| + 'N': '23456'
|
| + }
|
| + },
|
| + expected={
|
| + 'balance': {
|
| + 'ComparisonOperator': 'EQ', 'AttributeValueList': [{'N': '0'}]
|
| + },
|
| + },
|
| + conditional_operator=None)
|
| +
|
| + def side_effect(*args, **kwargs):
|
| + raise exceptions.ConditionalCheckFailedException(400, '', {})
|
| +
|
| + with mock.patch.object(
|
| + self.users.connection,
|
| + 'delete_item',
|
| + side_effect=side_effect) as mock_delete_item:
|
| + self.assertFalse(self.users.delete_item(expected={'balance__eq': 0},
|
| + username='johndoe', date_joined=23456))
|
| +
|
| def test_get_key_fields_no_schema_populated(self):
|
| expected = {
|
| "Table": {
|
| @@ -2086,7 +2229,7 @@
|
|
|
| mock_query.assert_called_once_with('users',
|
| consistent_read=False,
|
| - scan_index_forward=True,
|
| + scan_index_forward=False,
|
| index_name=None,
|
| attributes_to_get=None,
|
| limit=4,
|
| @@ -2096,7 +2239,9 @@
|
| 'ComparisonOperator': 'BETWEEN',
|
| }
|
| },
|
| - select=None
|
| + select=None,
|
| + query_filter=None,
|
| + conditional_operator=None
|
| )
|
|
|
| # Now alter the expected.
|
| @@ -2117,7 +2262,9 @@
|
| exclusive_start_key={
|
| 'username': 'adam',
|
| },
|
| - consistent=True
|
| + consistent=True,
|
| + query_filter=None,
|
| + conditional_operator='AND'
|
| )
|
| usernames = [res['username'] for res in results['results']]
|
| self.assertEqual(usernames, ['johndoe', 'jane', 'alice', 'bob'])
|
| @@ -2133,7 +2280,7 @@
|
| },
|
| index_name=None,
|
| attributes_to_get=None,
|
| - scan_index_forward=True,
|
| + scan_index_forward=False,
|
| limit=4,
|
| exclusive_start_key={
|
| 'username': {
|
| @@ -2141,7 +2288,9 @@
|
| },
|
| },
|
| consistent_read=True,
|
| - select=None
|
| + select=None,
|
| + query_filter=None,
|
| + conditional_operator='AND'
|
| )
|
|
|
| def test_private_scan(self):
|
| @@ -2203,7 +2352,8 @@
|
| limit=2,
|
| segment=None,
|
| attributes_to_get=None,
|
| - total_segments=None
|
| + total_segments=None,
|
| + conditional_operator=None
|
| )
|
|
|
| # Now alter the expected.
|
| @@ -2246,7 +2396,8 @@
|
| },
|
| segment=None,
|
| attributes_to_get=None,
|
| - total_segments=None
|
| + total_segments=None,
|
| + conditional_operator=None
|
| )
|
|
|
| def test_query(self):
|
| @@ -2266,7 +2417,7 @@
|
| 'last_key': 'jane',
|
| }
|
|
|
| - results = self.users.query(last_name__eq='Doe')
|
| + results = self.users.query_2(last_name__eq='Doe')
|
| self.assertTrue(isinstance(results, ResultSet))
|
| self.assertEqual(len(results._results), 0)
|
| self.assertEqual(results.the_callable, self.users._query)
|
| @@ -2320,7 +2471,7 @@
|
| 'last_key': 'jane',
|
| }
|
|
|
| - results = self.users.query(last_name__eq='Doe',
|
| + results = self.users.query_2(last_name__eq='Doe',
|
| attributes=['username'])
|
| self.assertTrue(isinstance(results, ResultSet))
|
| self.assertEqual(len(results._results), 0)
|
| @@ -2398,7 +2549,6 @@
|
|
|
| self.assertEqual(mock_scan_2.call_count, 1)
|
|
|
| -
|
| def test_scan_with_specific_attributes(self):
|
| items_1 = {
|
| 'results': [
|
| @@ -2431,7 +2581,6 @@
|
|
|
| self.assertEqual(mock_query.call_count, 1)
|
|
|
| -
|
| def test_count(self):
|
| expected = {
|
| "Table": {
|
| @@ -2477,6 +2626,41 @@
|
| return_value=expected) as mock_count:
|
| self.assertEqual(self.users.count(), 5)
|
|
|
| + def test_query_count_simple(self):
|
| + expected_0 = {
|
| + 'Count': 0.0,
|
| + }
|
| +
|
| + expected_1 = {
|
| + 'Count': 10.0,
|
| + }
|
| +
|
| + with mock.patch.object(
|
| + self.users.connection,
|
| + 'query',
|
| + return_value=expected_0) as mock_query:
|
| + results = self.users.query_count(username__eq='notmyname')
|
| + self.assertTrue(isinstance(results, int))
|
| + self.assertEqual(results, 0)
|
| + self.assertEqual(mock_query.call_count, 1)
|
| + self.assertIn('scan_index_forward', mock_query.call_args[1])
|
| + self.assertEqual(True, mock_query.call_args[1]['scan_index_forward'])
|
| + self.assertIn('limit', mock_query.call_args[1])
|
| + self.assertEqual(None, mock_query.call_args[1]['limit'])
|
| +
|
| + with mock.patch.object(
|
| + self.users.connection,
|
| + 'query',
|
| + return_value=expected_1) as mock_query:
|
| + results = self.users.query_count(username__gt='somename', consistent=True, scan_index_forward=False, limit=10)
|
| + self.assertTrue(isinstance(results, int))
|
| + self.assertEqual(results, 10)
|
| + self.assertEqual(mock_query.call_count, 1)
|
| + self.assertIn('scan_index_forward', mock_query.call_args[1])
|
| + self.assertEqual(False, mock_query.call_args[1]['scan_index_forward'])
|
| + self.assertIn('limit', mock_query.call_args[1])
|
| + self.assertEqual(10, mock_query.call_args[1]['limit'])
|
| +
|
| def test_private_batch_get(self):
|
| expected = {
|
| "ConsumedCapacity": {
|
|
|