| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | from __future__ import unicode_literals, print_function | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  | from nose.tools import assert_raises | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | import boto3 | 
					
						
							|  |  |  | from moto import mock_dynamodb2, mock_dynamodbstreams | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | class TestCore: | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |     stream_arn = None | 
					
						
							|  |  |  |     mocks = [] | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |     def setup(self): | 
					
						
							|  |  |  |         self.mocks = [mock_dynamodb2(), mock_dynamodbstreams()] | 
					
						
							|  |  |  |         for m in self.mocks: | 
					
						
							|  |  |  |             m.start() | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |         # create a table with a stream | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodb", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.create_table( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             TableName="test-streams", | 
					
						
							|  |  |  |             KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}], | 
					
						
							|  |  |  |             AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}], | 
					
						
							|  |  |  |             ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1}, | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |             StreamSpecification={ | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                 "StreamEnabled": True, | 
					
						
							|  |  |  |                 "StreamViewType": "NEW_AND_OLD_IMAGES", | 
					
						
							|  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         self.stream_arn = resp["TableDescription"]["LatestStreamArn"] | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def teardown(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodb", region_name="us-east-1") | 
					
						
							|  |  |  |         conn.delete_table(TableName="test-streams") | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |         self.stream_arn = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for m in self.mocks: | 
					
						
							|  |  |  |             m.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_verify_stream(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodb", region_name="us-east-1") | 
					
						
							|  |  |  |         resp = conn.describe_table(TableName="test-streams") | 
					
						
							|  |  |  |         assert "LatestStreamArn" in resp["Table"] | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_describe_stream(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodbstreams", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.describe_stream(StreamArn=self.stream_arn) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert "StreamDescription" in resp | 
					
						
							|  |  |  |         desc = resp["StreamDescription"] | 
					
						
							|  |  |  |         assert desc["StreamArn"] == self.stream_arn | 
					
						
							|  |  |  |         assert desc["TableName"] == "test-streams" | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_list_streams(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodbstreams", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.list_streams() | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert resp["Streams"][0]["StreamArn"] == self.stream_arn | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         resp = conn.list_streams(TableName="no-stream") | 
					
						
							|  |  |  |         assert not resp["Streams"] | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_shard_iterator(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodbstreams", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.describe_stream(StreamArn=self.stream_arn) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |         resp = conn.get_shard_iterator( | 
					
						
							|  |  |  |             StreamArn=self.stream_arn, | 
					
						
							|  |  |  |             ShardId=shard_id, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             ShardIteratorType="TRIM_HORIZON", | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert "ShardIterator" in resp | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_shard_iterator_at_sequence_number(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodbstreams", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.describe_stream(StreamArn=self.stream_arn) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         resp = conn.get_shard_iterator( | 
					
						
							|  |  |  |             StreamArn=self.stream_arn, | 
					
						
							|  |  |  |             ShardId=shard_id, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             ShardIteratorType="AT_SEQUENCE_NUMBER", | 
					
						
							|  |  |  |             SequenceNumber=resp["StreamDescription"]["Shards"][0][ | 
					
						
							|  |  |  |                 "SequenceNumberRange" | 
					
						
							|  |  |  |             ]["StartingSequenceNumber"], | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert "ShardIterator" in resp | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_shard_iterator_after_sequence_number(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodbstreams", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.describe_stream(StreamArn=self.stream_arn) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         resp = conn.get_shard_iterator( | 
					
						
							|  |  |  |             StreamArn=self.stream_arn, | 
					
						
							|  |  |  |             ShardId=shard_id, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             ShardIteratorType="AFTER_SEQUENCE_NUMBER", | 
					
						
							|  |  |  |             SequenceNumber=resp["StreamDescription"]["Shards"][0][ | 
					
						
							|  |  |  |                 "SequenceNumberRange" | 
					
						
							|  |  |  |             ]["StartingSequenceNumber"], | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert "ShardIterator" in resp | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |     def test_get_records_empty(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodbstreams", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.describe_stream(StreamArn=self.stream_arn) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |         resp = conn.get_shard_iterator( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             StreamArn=self.stream_arn, ShardId=shard_id, ShardIteratorType="LATEST" | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         iterator_id = resp["ShardIterator"] | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.get_records(ShardIterator=iterator_id) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert "Records" in resp | 
					
						
							|  |  |  |         assert len(resp["Records"]) == 0 | 
					
						
							| 
									
										
										
										
											2018-11-07 17:10:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |     def test_get_records_seq(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodb", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         conn.put_item( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             TableName="test-streams", | 
					
						
							|  |  |  |             Item={"id": {"S": "entry1"}, "first_col": {"S": "foo"}}, | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |         ) | 
					
						
							|  |  |  |         conn.put_item( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             TableName="test-streams", | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |             Item={ | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                 "id": {"S": "entry1"}, | 
					
						
							|  |  |  |                 "first_col": {"S": "bar"}, | 
					
						
							|  |  |  |                 "second_col": {"S": "baz"}, | 
					
						
							|  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn.delete_item(TableName="test-streams", Key={"id": {"S": "entry1"}}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         conn = boto3.client("dynamodbstreams", region_name="us-east-1") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |         resp = conn.describe_stream(StreamArn=self.stream_arn) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |         resp = conn.get_shard_iterator( | 
					
						
							|  |  |  |             StreamArn=self.stream_arn, | 
					
						
							|  |  |  |             ShardId=shard_id, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             ShardIteratorType="TRIM_HORIZON", | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         iterator_id = resp["ShardIterator"] | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = conn.get_records(ShardIterator=iterator_id) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert len(resp["Records"]) == 3 | 
					
						
							|  |  |  |         assert resp["Records"][0]["eventName"] == "INSERT" | 
					
						
							|  |  |  |         assert resp["Records"][1]["eventName"] == "MODIFY" | 
					
						
							|  |  |  |         assert resp["Records"][2]["eventName"] == "DELETE" | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         sequence_number_modify = resp["Records"][1]["dynamodb"]["SequenceNumber"] | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 10:54:54 -05:00
										 |  |  |         # now try fetching from the next shard iterator, it should be | 
					
						
							|  |  |  |         # empty | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         resp = conn.get_records(ShardIterator=resp["NextShardIterator"]) | 
					
						
							|  |  |  |         assert len(resp["Records"]) == 0 | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-29 21:21:02 -05:00
										 |  |  |         # check that if we get the shard iterator AT_SEQUENCE_NUMBER will get the MODIFY event | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         resp = conn.get_shard_iterator( | 
					
						
							|  |  |  |             StreamArn=self.stream_arn, | 
					
						
							|  |  |  |             ShardId=shard_id, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             ShardIteratorType="AT_SEQUENCE_NUMBER", | 
					
						
							|  |  |  |             SequenceNumber=sequence_number_modify, | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         iterator_id = resp["ShardIterator"] | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         resp = conn.get_records(ShardIterator=iterator_id) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert len(resp["Records"]) == 2 | 
					
						
							|  |  |  |         assert resp["Records"][0]["eventName"] == "MODIFY" | 
					
						
							|  |  |  |         assert resp["Records"][1]["eventName"] == "DELETE" | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-29 21:21:02 -05:00
										 |  |  |         # check that if we get the shard iterator AFTER_SEQUENCE_NUMBER will get the DELETE event | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         resp = conn.get_shard_iterator( | 
					
						
							|  |  |  |             StreamArn=self.stream_arn, | 
					
						
							|  |  |  |             ShardId=shard_id, | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             ShardIteratorType="AFTER_SEQUENCE_NUMBER", | 
					
						
							|  |  |  |             SequenceNumber=sequence_number_modify, | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         iterator_id = resp["ShardIterator"] | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  |         resp = conn.get_records(ShardIterator=iterator_id) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert len(resp["Records"]) == 1 | 
					
						
							|  |  |  |         assert resp["Records"][0]["eventName"] == "DELETE" | 
					
						
							| 
									
										
										
										
											2019-07-29 21:13:58 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | class TestEdges: | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |     mocks = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setup(self): | 
					
						
							|  |  |  |         self.mocks = [mock_dynamodb2(), mock_dynamodbstreams()] | 
					
						
							|  |  |  |         for m in self.mocks: | 
					
						
							|  |  |  |             m.start() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def teardown(self): | 
					
						
							|  |  |  |         for m in self.mocks: | 
					
						
							|  |  |  |             m.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_enable_stream_on_table(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         conn = boto3.client("dynamodb", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         resp = conn.create_table( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             TableName="test-streams", | 
					
						
							|  |  |  |             KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}], | 
					
						
							|  |  |  |             AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}], | 
					
						
							|  |  |  |             ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1}, | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert "StreamSpecification" not in resp["TableDescription"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         resp = conn.update_table( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             TableName="test-streams", | 
					
						
							| 
									
										
										
										
											2019-11-21 17:00:18 -05:00
										 |  |  |             StreamSpecification={"StreamViewType": "KEYS_ONLY", "StreamEnabled": True}, | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert "StreamSpecification" in resp["TableDescription"] | 
					
						
							|  |  |  |         assert resp["TableDescription"]["StreamSpecification"] == { | 
					
						
							|  |  |  |             "StreamEnabled": True, | 
					
						
							|  |  |  |             "StreamViewType": "KEYS_ONLY", | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert "LatestStreamLabel" in resp["TableDescription"] | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # now try to enable it again | 
					
						
							| 
									
										
										
										
											2018-11-08 13:57:44 -05:00
										 |  |  |         with assert_raises(conn.exceptions.ResourceInUseException): | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |             resp = conn.update_table( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                 TableName="test-streams", | 
					
						
							| 
									
										
										
										
											2019-11-21 17:53:58 -05:00
										 |  |  |                 StreamSpecification={ | 
					
						
							|  |  |  |                     "StreamViewType": "OLD_IMAGES", | 
					
						
							|  |  |  |                     "StreamEnabled": True, | 
					
						
							|  |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |     def test_stream_with_range_key(self): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         dyn = boto3.client("dynamodb", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = dyn.create_table( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             TableName="test-streams", | 
					
						
							|  |  |  |             KeySchema=[ | 
					
						
							|  |  |  |                 {"AttributeName": "id", "KeyType": "HASH"}, | 
					
						
							|  |  |  |                 {"AttributeName": "color", "KeyType": "RANGE"}, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             AttributeDefinitions=[ | 
					
						
							|  |  |  |                 {"AttributeName": "id", "AttributeType": "S"}, | 
					
						
							|  |  |  |                 {"AttributeName": "color", "AttributeType": "S"}, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             ProvisionedThroughput={"ReadCapacityUnits": 1, "WriteCapacityUnits": 1}, | 
					
						
							| 
									
										
										
										
											2019-11-21 17:00:18 -05:00
										 |  |  |             StreamSpecification={"StreamViewType": "NEW_IMAGES", "StreamEnabled": True}, | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         stream_arn = resp["TableDescription"]["LatestStreamArn"] | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         streams = boto3.client("dynamodbstreams", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         resp = streams.describe_stream(StreamArn=stream_arn) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         shard_id = resp["StreamDescription"]["Shards"][0]["ShardId"] | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         resp = streams.get_shard_iterator( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             StreamArn=stream_arn, ShardId=shard_id, ShardIteratorType="LATEST" | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         iterator_id = resp["ShardIterator"] | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         dyn.put_item( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             TableName="test-streams", Item={"id": {"S": "row1"}, "color": {"S": "blue"}} | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         ) | 
					
						
							|  |  |  |         dyn.put_item( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             TableName="test-streams", | 
					
						
							|  |  |  |             Item={"id": {"S": "row2"}, "color": {"S": "green"}}, | 
					
						
							| 
									
										
										
										
											2018-11-08 13:22:24 -05:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         resp = streams.get_records(ShardIterator=iterator_id) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         assert len(resp["Records"]) == 2 | 
					
						
							|  |  |  |         assert resp["Records"][0]["eventName"] == "INSERT" | 
					
						
							|  |  |  |         assert resp["Records"][1]["eventName"] == "INSERT" |