Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: third_party/gsutil/boto/tests/dynamodb/test_layer2.py

Issue 10199002: Upgrade gsutil to 3.4 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2012 Mitch Garnaat http://garnaat.org/
2 # All rights reserved.
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish, dis-
8 # tribute, sublicense, and/or sell copies of the Software, and to permit
9 # persons to whom the Software is furnished to do so, subject to the fol-
10 # lowing conditions:
11 #
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 # IN THE SOFTWARE.
22
23 """
24 Tests for Layer2 of Amazon DynamoDB
25 """
26
27 import unittest
28 import time
29 import uuid
30 from boto.dynamodb.exceptions import DynamoDBKeyNotFoundError, DynamoDBItemError
31 from boto.dynamodb.layer2 import Layer2
32 from boto.dynamodb.types import get_dynamodb_type
33 from boto.dynamodb.condition import *
34
35 class DynamoDBLayer2Test (unittest.TestCase):
36
37 def test_layer2_basic(self):
38 print '--- running Amazon DynamoDB Layer2 tests ---'
39 c = Layer2()
40
41 # First create a schema for the table
42 hash_key_name = 'forum_name'
43 hash_key_proto_value = ''
44 range_key_name = 'subject'
45 range_key_proto_value = ''
46 schema = c.create_schema(hash_key_name, hash_key_proto_value,
47 range_key_name, range_key_proto_value)
48
49 # Create another schema without a range key
50 schema2 = c.create_schema('post_id', '')
51
52 # Now create a table
53 index = int(time.time())
54 table_name = 'test-%d' % index
55 read_units = 5
56 write_units = 5
57 table = c.create_table(table_name, schema, read_units, write_units)
58 assert table.name == table_name
59 assert table.schema.hash_key_name == hash_key_name
60 assert table.schema.hash_key_type == get_dynamodb_type(hash_key_proto_va lue)
61 assert table.schema.range_key_name == range_key_name
62 assert table.schema.range_key_type == get_dynamodb_type(range_key_proto_ value)
63 assert table.read_units == read_units
64 assert table.write_units == write_units
65 assert table.item_count == 0
66 assert table.size_bytes == 0
67
68 # Create the second table
69 table2_name = 'test-%d' % (index + 1)
70 table2 = c.create_table(table2_name, schema2, read_units, write_units)
71
72 # Wait for table to become active
73 table.refresh(wait_for_active=True)
74 table2.refresh(wait_for_active=True)
75
76 # List tables and make sure new one is there
77 table_names = c.list_tables()
78 assert table_name in table_names
79 assert table2_name in table_names
80
81 # Update the tables ProvisionedThroughput
82 new_read_units = 10
83 new_write_units = 5
84 table.update_throughput(new_read_units, new_write_units)
85
86 # Wait for table to be updated
87 table.refresh(wait_for_active=True)
88 assert table.read_units == new_read_units
89 assert table.write_units == new_write_units
90
91 # Put an item
92 item1_key = 'Amazon DynamoDB'
93 item1_range = 'DynamoDB Thread 1'
94 item1_attrs = {
95 'Message': 'DynamoDB thread 1 message text',
96 'LastPostedBy': 'User A',
97 'Views': 0,
98 'Replies': 0,
99 'Answered': 0,
100 'Public': True,
101 'Tags': set(['index', 'primarykey', 'table']),
102 'LastPostDateTime': '12/9/2011 11:36:03 PM'}
103
104 # Test a few corner cases with new_item
105 # First, try not supplying a hash_key
106 self.assertRaises(DynamoDBItemError,
107 table.new_item, None, item1_range, item1_attrs)
108
109 # Try supplying a hash but no range
110 self.assertRaises(DynamoDBItemError,
111 table.new_item, item1_key, None, item1_attrs)
112
113 # Try supplying a hash_key as an arg and as an item in attrs
114 item1_attrs[hash_key_name] = 'foo'
115 foobar_item = table.new_item(item1_key, item1_range, item1_attrs)
116 assert foobar_item.hash_key == item1_key
117
118 # Try supplying a range_key as an arg and as an item in attrs
119 item1_attrs[range_key_name] = 'bar'
120 foobar_item = table.new_item(item1_key, item1_range, item1_attrs)
121 assert foobar_item.range_key == item1_range
122
123 # Try supplying hash and range key in attrs dict
124 foobar_item = table.new_item(attrs=item1_attrs)
125 assert foobar_item.hash_key == 'foo'
126 assert foobar_item.range_key == 'bar'
127
128 del item1_attrs[hash_key_name]
129 del item1_attrs[range_key_name]
130
131 item1 = table.new_item(item1_key, item1_range, item1_attrs)
132 # make sure the put() succeeds
133 try:
134 item1.put()
135 except c.layer1.ResponseError, e:
136 raise Exception("Item put failed: %s" % e)
137
138 # Try to get an item that does not exist.
139 self.assertRaises(DynamoDBKeyNotFoundError,
140 table.get_item, 'bogus_key', item1_range)
141
142 # Now do a consistent read and check results
143 item1_copy = table.get_item(item1_key, item1_range,
144 consistent_read=True)
145 assert item1_copy.hash_key == item1.hash_key
146 assert item1_copy.range_key == item1.range_key
147 for attr_name in item1_copy:
148 val = item1_copy[attr_name]
149 if isinstance(val, (int, long, float, basestring)):
150 assert val == item1[attr_name]
151
152 # Try retrieving only select attributes
153 attributes = ['Message', 'Views']
154 item1_small = table.get_item(item1_key, item1_range,
155 attributes_to_get=attributes,
156 consistent_read=True)
157 for attr_name in item1_small:
158 # The item will include the attributes we asked for as
159 # well as the hashkey and rangekey, so filter those out.
160 if attr_name not in (item1_small.hash_key_name,
161 item1_small.range_key_name):
162 assert attr_name in attributes
163
164 self.assertTrue(table.has_item(item1_key, range_key=item1_range,
165 consistent_read=True))
166
167 # Try to delete the item with the wrong Expected value
168 expected = {'Views': 1}
169 try:
170 item1.delete(expected_value=expected)
171 except c.layer1.ResponseError, e:
172 assert e.error_code == 'ConditionalCheckFailedException'
173 else:
174 raise Exception("Expected Value condition failed")
175
176 # Try to delete a value while expecting a non-existant attribute
177 expected = {'FooBar': True}
178 try:
179 item1.delete(expected_value=expected)
180 except c.layer1.ResponseError, e:
181 pass
182
183 # Now update the existing object
184 item1.add_attribute('Replies', 2)
185
186 removed_attr = 'Public'
187 item1.delete_attribute(removed_attr)
188
189 removed_tag = item1_attrs['Tags'].copy().pop()
190 item1.delete_attribute('Tags', set([removed_tag]))
191
192 replies_by_set = set(['Adam', 'Arnie'])
193 item1.put_attribute('RepliesBy', replies_by_set)
194 retvals = item1.save(return_values='ALL_OLD')
195 # Need more tests here for variations on return_values
196 assert 'Attributes' in retvals
197
198 # Check for correct updates
199 item1_updated = table.get_item(item1_key, item1_range,
200 consistent_read=True)
201 assert item1_updated['Replies'] == item1_attrs['Replies'] + 2
202 self.assertFalse(item1_updated.has_key(removed_attr))
203 self.assertTrue(removed_tag not in item1_updated['Tags'])
204 self.assertTrue(item1_updated.has_key('RepliesBy'))
205 self.assertTrue(item1_updated['RepliesBy'] == replies_by_set)
206
207 # Put a few more items into the table
208 item2_key = 'Amazon DynamoDB'
209 item2_range = 'DynamoDB Thread 2'
210 item2_attrs = {
211 'Message': 'DynamoDB thread 2 message text',
212 'LastPostedBy': 'User A',
213 'Views': 0,
214 'Replies': 0,
215 'Answered': 0,
216 'Tags': set(["index", "primarykey", "table"]),
217 'LastPost2DateTime': '12/9/2011 11:36:03 PM'}
218 item2 = table.new_item(item2_key, item2_range, item2_attrs)
219 item2.put()
220
221 item3_key = 'Amazon S3'
222 item3_range = 'S3 Thread 1'
223 item3_attrs = {
224 'Message': 'S3 Thread 1 message text',
225 'LastPostedBy': 'User A',
226 'Views': 0,
227 'Replies': 0,
228 'Answered': 0,
229 'Tags': set(['largeobject', 'multipart upload']),
230 'LastPostDateTime': '12/9/2011 11:36:03 PM'
231 }
232 item3 = table.new_item(item3_key, item3_range, item3_attrs)
233 item3.put()
234
235 # Put an item into the second table
236 table2_item1_key = uuid.uuid4().hex
237 table2_item1_attrs = {
238 'DateTimePosted': '25/1/2011 12:34:56 PM',
239 'Text': 'I think boto rocks and so does DynamoDB'
240 }
241 table2_item1 = table2.new_item(table2_item1_key,
242 attrs=table2_item1_attrs)
243 table2_item1.put()
244
245 # Try a few queries
246 items = table.query('Amazon DynamoDB', BEGINS_WITH('DynamoDB'))
247 n = 0
248 for item in items:
249 n += 1
250 assert n == 2
251
252 items = table.query('Amazon DynamoDB', BEGINS_WITH('DynamoDB'),
253 request_limit=1, max_results=1)
254 n = 0
255 for item in items:
256 n += 1
257 assert n == 1
258
259 # Try a few scans
260 items = table.scan()
261 n = 0
262 for item in items:
263 n += 1
264 assert n == 3
265
266 items = table.scan({'Replies': GT(0)})
267 n = 0
268 for item in items:
269 n += 1
270 assert n == 1
271
272 # Test some integer and float attributes
273 integer_value = 42
274 float_value = 345.678
275 item3['IntAttr'] = integer_value
276 item3['FloatAttr'] = float_value
277
278 # Test booleans
279 item3['TrueBoolean'] = True
280 item3['FalseBoolean'] = False
281
282 # Test some set values
283 integer_set = set([1,2,3,4,5])
284 float_set = set([1.1, 2.2, 3.3, 4.4, 5.5])
285 mixed_set = set([1, 2, 3.3, 4, 5.555])
286 str_set = set(['foo', 'bar', 'fie', 'baz'])
287 item3['IntSetAttr'] = integer_set
288 item3['FloatSetAttr'] = float_set
289 item3['MixedSetAttr'] = mixed_set
290 item3['StrSetAttr'] = str_set
291 item3.put()
292
293 # Now do a consistent read
294 item4 = table.get_item(item3_key, item3_range, consistent_read=True)
295 assert item4['IntAttr'] == integer_value
296 assert item4['FloatAttr'] == float_value
297 assert item4['TrueBoolean'] == True
298 assert item4['FalseBoolean'] == False
299 # The values will not necessarily be in the same order as when
300 # we wrote them to the DB.
301 for i in item4['IntSetAttr']:
302 assert i in integer_set
303 for i in item4['FloatSetAttr']:
304 assert i in float_set
305 for i in item4['MixedSetAttr']:
306 assert i in mixed_set
307 for i in item4['StrSetAttr']:
308 assert i in str_set
309
310 # Try a batch get
311 batch_list = c.new_batch_list()
312 batch_list.add_batch(table, [(item2_key, item2_range),
313 (item3_key, item3_range)])
314 response = batch_list.submit()
315 assert len(response['Responses'][table.name]['Items']) == 2
316
317 # Try queries
318 results = table.query('Amazon DynamoDB', BEGINS_WITH('DynamoDB'))
319 n = 0
320 for item in results:
321 n += 1
322 assert n == 2
323
324 # Try scans
325 results = table.scan({'Tags': CONTAINS('table')})
326 n = 0
327 for item in results:
328 n += 1
329 assert n == 2
330
331 # Try to delete the item with the right Expected value
332 expected = {'Views': 0}
333 item1.delete(expected_value=expected)
334
335 self.assertFalse(table.has_item(item1_key, range_key=item1_range,
336 consistent_read=True))
337 # Now delete the remaining items
338 ret_vals = item2.delete(return_values='ALL_OLD')
339 # some additional checks here would be useful
340 assert ret_vals['Attributes'][hash_key_name] == item2_key
341 assert ret_vals['Attributes'][range_key_name] == item2_range
342
343 item3.delete()
344 table2_item1.delete()
345
346 # Now delete the tables
347 table.delete()
348 table2.delete()
349 assert table.status == 'DELETING'
350 assert table2.status == 'DELETING'
351
352 print '--- tests completed ---'
OLDNEW
« no previous file with comments | « third_party/gsutil/boto/tests/dynamodb/test_layer1.py ('k') | third_party/gsutil/boto/tests/ec2/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698