Techdebt: Replace sure with regular assertions in Kinesis (#6579)
This commit is contained in:
		
							parent
							
								
									58a981a002
								
							
						
					
					
						commit
						6843eb4c86
					
				@ -10,8 +10,6 @@ from dateutil.tz import tzlocal
 | 
				
			|||||||
from moto import mock_kinesis
 | 
					from moto import mock_kinesis
 | 
				
			||||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
 | 
					from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sure  # noqa # pylint: disable=unused-import
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
def test_stream_creation_on_demand():
 | 
					def test_stream_creation_on_demand():
 | 
				
			||||||
@ -24,7 +22,7 @@ def test_stream_creation_on_demand():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # AWS starts with 4 shards by default
 | 
					    # AWS starts with 4 shards by default
 | 
				
			||||||
    shard_list = client.list_shards(StreamARN=stream_arn)["Shards"]
 | 
					    shard_list = client.list_shards(StreamARN=stream_arn)["Shards"]
 | 
				
			||||||
    shard_list.should.have.length_of(4)
 | 
					    assert len(shard_list) == 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Cannot update-shard-count when we're in on-demand mode
 | 
					    # Cannot update-shard-count when we're in on-demand mode
 | 
				
			||||||
    with pytest.raises(ClientError) as exc:
 | 
					    with pytest.raises(ClientError) as exc:
 | 
				
			||||||
@ -32,9 +30,10 @@ def test_stream_creation_on_demand():
 | 
				
			|||||||
            StreamARN=stream_arn, TargetShardCount=3, ScalingType="UNIFORM_SCALING"
 | 
					            StreamARN=stream_arn, TargetShardCount=3, ScalingType="UNIFORM_SCALING"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ValidationException")
 | 
					    assert err["Code"] == "ValidationException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        f"Request is invalid. Stream my_stream under account {ACCOUNT_ID} is in On-Demand mode."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == f"Request is invalid. Stream my_stream under account {ACCOUNT_ID} is in On-Demand mode."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -54,7 +53,7 @@ def test_update_stream_mode():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream_summary(StreamName="my_stream")
 | 
					    resp = client.describe_stream_summary(StreamName="my_stream")
 | 
				
			||||||
    stream = resp["StreamDescriptionSummary"]
 | 
					    stream = resp["StreamDescriptionSummary"]
 | 
				
			||||||
    stream.should.have.key("StreamModeDetails").equals({"StreamMode": "PROVISIONED"})
 | 
					    assert stream["StreamModeDetails"] == {"StreamMode": "PROVISIONED"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -63,27 +62,25 @@ def test_describe_non_existent_stream():
 | 
				
			|||||||
    with pytest.raises(ClientError) as exc:
 | 
					    with pytest.raises(ClientError) as exc:
 | 
				
			||||||
        client.describe_stream_summary(StreamName="not-a-stream")
 | 
					        client.describe_stream_summary(StreamName="not-a-stream")
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ResourceNotFoundException")
 | 
					    assert err["Code"] == "ResourceNotFoundException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert err["Message"] == "Stream not-a-stream under account 123456789012 not found."
 | 
				
			||||||
        "Stream not-a-stream under account 123456789012 not found."
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
def test_list_and_delete_stream():
 | 
					def test_list_and_delete_stream():
 | 
				
			||||||
    client = boto3.client("kinesis", region_name="us-west-2")
 | 
					    client = boto3.client("kinesis", region_name="us-west-2")
 | 
				
			||||||
    client.list_streams()["StreamNames"].should.have.length_of(0)
 | 
					    assert len(client.list_streams()["StreamNames"]) == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.create_stream(StreamName="stream1", ShardCount=1)
 | 
					    client.create_stream(StreamName="stream1", ShardCount=1)
 | 
				
			||||||
    client.create_stream(StreamName="stream2", ShardCount=1)
 | 
					    client.create_stream(StreamName="stream2", ShardCount=1)
 | 
				
			||||||
    client.list_streams()["StreamNames"].should.have.length_of(2)
 | 
					    assert len(client.list_streams()["StreamNames"]) == 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.delete_stream(StreamName="stream1")
 | 
					    client.delete_stream(StreamName="stream1")
 | 
				
			||||||
    client.list_streams()["StreamNames"].should.have.length_of(1)
 | 
					    assert len(client.list_streams()["StreamNames"]) == 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream_arn = get_stream_arn(client, "stream2")
 | 
					    stream_arn = get_stream_arn(client, "stream2")
 | 
				
			||||||
    client.delete_stream(StreamARN=stream_arn)
 | 
					    client.delete_stream(StreamARN=stream_arn)
 | 
				
			||||||
    client.list_streams()["StreamNames"].should.have.length_of(0)
 | 
					    assert len(client.list_streams()["StreamNames"]) == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -92,10 +89,8 @@ def test_delete_unknown_stream():
 | 
				
			|||||||
    with pytest.raises(ClientError) as exc:
 | 
					    with pytest.raises(ClientError) as exc:
 | 
				
			||||||
        client.delete_stream(StreamName="not-a-stream")
 | 
					        client.delete_stream(StreamName="not-a-stream")
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ResourceNotFoundException")
 | 
					    assert err["Code"] == "ResourceNotFoundException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert err["Message"] == "Stream not-a-stream under account 123456789012 not found."
 | 
				
			||||||
        "Stream not-a-stream under account 123456789012 not found."
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -108,13 +103,13 @@ def test_list_many_streams():
 | 
				
			|||||||
    resp = conn.list_streams()
 | 
					    resp = conn.list_streams()
 | 
				
			||||||
    stream_names = resp["StreamNames"]
 | 
					    stream_names = resp["StreamNames"]
 | 
				
			||||||
    has_more_streams = resp["HasMoreStreams"]
 | 
					    has_more_streams = resp["HasMoreStreams"]
 | 
				
			||||||
    stream_names.should.have.length_of(10)
 | 
					    assert len(stream_names) == 10
 | 
				
			||||||
    has_more_streams.should.be(True)
 | 
					    assert has_more_streams is True
 | 
				
			||||||
    resp2 = conn.list_streams(ExclusiveStartStreamName=stream_names[-1])
 | 
					    resp2 = conn.list_streams(ExclusiveStartStreamName=stream_names[-1])
 | 
				
			||||||
    stream_names = resp2["StreamNames"]
 | 
					    stream_names = resp2["StreamNames"]
 | 
				
			||||||
    has_more_streams = resp2["HasMoreStreams"]
 | 
					    has_more_streams = resp2["HasMoreStreams"]
 | 
				
			||||||
    stream_names.should.have.length_of(1)
 | 
					    assert len(stream_names) == 1
 | 
				
			||||||
    has_more_streams.should.equal(False)
 | 
					    assert has_more_streams is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -127,18 +122,19 @@ def test_describe_stream_summary():
 | 
				
			|||||||
    resp = conn.describe_stream_summary(StreamName=stream_name)
 | 
					    resp = conn.describe_stream_summary(StreamName=stream_name)
 | 
				
			||||||
    stream = resp["StreamDescriptionSummary"]
 | 
					    stream = resp["StreamDescriptionSummary"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream["StreamName"].should.equal(stream_name)
 | 
					    assert stream["StreamName"] == stream_name
 | 
				
			||||||
    stream["OpenShardCount"].should.equal(shard_count)
 | 
					    assert stream["OpenShardCount"] == shard_count
 | 
				
			||||||
    stream["StreamARN"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        f"arn:aws:kinesis:us-west-2:{ACCOUNT_ID}:stream/{stream_name}"
 | 
					        stream["StreamARN"]
 | 
				
			||||||
 | 
					        == f"arn:aws:kinesis:us-west-2:{ACCOUNT_ID}:stream/{stream_name}"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    stream["StreamStatus"].should.equal("ACTIVE")
 | 
					    assert stream["StreamStatus"] == "ACTIVE"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream_arn = get_stream_arn(conn, stream_name)
 | 
					    stream_arn = get_stream_arn(conn, stream_name)
 | 
				
			||||||
    resp = conn.describe_stream_summary(StreamARN=stream_arn)
 | 
					    resp = conn.describe_stream_summary(StreamARN=stream_arn)
 | 
				
			||||||
    stream = resp["StreamDescriptionSummary"]
 | 
					    stream = resp["StreamDescriptionSummary"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream["StreamName"].should.equal(stream_name)
 | 
					    assert stream["StreamName"] == stream_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -156,8 +152,8 @@ def test_basic_shard_iterator():
 | 
				
			|||||||
    shard_iterator = resp["ShardIterator"]
 | 
					    shard_iterator = resp["ShardIterator"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp = client.get_records(ShardIterator=shard_iterator)
 | 
					    resp = client.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
    resp.should.have.key("Records").length_of(0)
 | 
					    assert len(resp["Records"]) == 0
 | 
				
			||||||
    resp.should.have.key("MillisBehindLatest").equal(0)
 | 
					    assert resp["MillisBehindLatest"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -179,8 +175,8 @@ def test_basic_shard_iterator_by_stream_arn():
 | 
				
			|||||||
    resp = client.get_records(
 | 
					    resp = client.get_records(
 | 
				
			||||||
        StreamARN=stream["StreamARN"], ShardIterator=shard_iterator
 | 
					        StreamARN=stream["StreamARN"], ShardIterator=shard_iterator
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    resp.should.have.key("Records").length_of(0)
 | 
					    assert len(resp["Records"]) == 0
 | 
				
			||||||
    resp.should.have.key("MillisBehindLatest").equal(0)
 | 
					    assert resp["MillisBehindLatest"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -195,11 +191,12 @@ def test_get_invalid_shard_iterator():
 | 
				
			|||||||
            StreamName=stream_name, ShardId="123", ShardIteratorType="TRIM_HORIZON"
 | 
					            StreamName=stream_name, ShardId="123", ShardIteratorType="TRIM_HORIZON"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ResourceNotFoundException")
 | 
					    assert err["Code"] == "ResourceNotFoundException"
 | 
				
			||||||
    # There is some magic in AWS, that '123' is automatically converted into 'shardId-000000000123'
 | 
					    # There is some magic in AWS, that '123' is automatically converted into 'shardId-000000000123'
 | 
				
			||||||
    # AWS itself returns this normalized ID in the error message, not the given id
 | 
					    # AWS itself returns this normalized ID in the error message, not the given id
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        f"Shard 123 in stream {stream_name} under account {ACCOUNT_ID} does not exist"
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == f"Shard 123 in stream {stream_name} under account {ACCOUNT_ID} does not exist"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -227,12 +224,12 @@ def test_put_records():
 | 
				
			|||||||
    shard_iterator = resp["ShardIterator"]
 | 
					    shard_iterator = resp["ShardIterator"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp = client.get_records(ShardIterator=shard_iterator)
 | 
					    resp = client.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
    resp["Records"].should.have.length_of(5)
 | 
					    assert len(resp["Records"]) == 5
 | 
				
			||||||
    record = resp["Records"][0]
 | 
					    record = resp["Records"][0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    record["Data"].should.equal(data)
 | 
					    assert record["Data"] == data
 | 
				
			||||||
    record["PartitionKey"].should.equal(partition_key)
 | 
					    assert record["PartitionKey"] == partition_key
 | 
				
			||||||
    record["SequenceNumber"].should.equal("1")
 | 
					    assert record["SequenceNumber"] == "1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -257,12 +254,12 @@ def test_get_records_limit():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Retrieve only 3 records
 | 
					    # Retrieve only 3 records
 | 
				
			||||||
    resp = client.get_records(ShardIterator=shard_iterator, Limit=3)
 | 
					    resp = client.get_records(ShardIterator=shard_iterator, Limit=3)
 | 
				
			||||||
    resp["Records"].should.have.length_of(3)
 | 
					    assert len(resp["Records"]) == 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Then get the rest of the results
 | 
					    # Then get the rest of the results
 | 
				
			||||||
    next_shard_iterator = resp["NextShardIterator"]
 | 
					    next_shard_iterator = resp["NextShardIterator"]
 | 
				
			||||||
    response = client.get_records(ShardIterator=next_shard_iterator)
 | 
					    response = client.get_records(ShardIterator=next_shard_iterator)
 | 
				
			||||||
    response["Records"].should.have.length_of(2)
 | 
					    assert len(response["Records"]) == 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -300,8 +297,8 @@ def test_get_records_at_sequence_number():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.get_records(ShardIterator=shard_iterator)
 | 
					    resp = client.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
    # And the first result returned should be the second item
 | 
					    # And the first result returned should be the second item
 | 
				
			||||||
    resp["Records"][0]["SequenceNumber"].should.equal(sequence_nr)
 | 
					    assert resp["Records"][0]["SequenceNumber"] == sequence_nr
 | 
				
			||||||
    resp["Records"][0]["Data"].should.equal(b"data_2")
 | 
					    assert resp["Records"][0]["Data"] == b"data_2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -339,9 +336,9 @@ def test_get_records_after_sequence_number():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.get_records(ShardIterator=shard_iterator)
 | 
					    resp = client.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
    # And the first result returned should be the second item
 | 
					    # And the first result returned should be the second item
 | 
				
			||||||
    resp["Records"][0]["SequenceNumber"].should.equal("3")
 | 
					    assert resp["Records"][0]["SequenceNumber"] == "3"
 | 
				
			||||||
    resp["Records"][0]["Data"].should.equal(b"data_3")
 | 
					    assert resp["Records"][0]["Data"] == b"data_3"
 | 
				
			||||||
    resp["MillisBehindLatest"].should.equal(0)
 | 
					    assert resp["MillisBehindLatest"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -383,11 +380,11 @@ def test_get_records_latest():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.get_records(ShardIterator=shard_iterator)
 | 
					    resp = client.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
    # And the first result returned should be the second item
 | 
					    # And the first result returned should be the second item
 | 
				
			||||||
    resp["Records"].should.have.length_of(1)
 | 
					    assert len(resp["Records"]) == 1
 | 
				
			||||||
    resp["Records"][0]["SequenceNumber"].should.equal("5")
 | 
					    assert resp["Records"][0]["SequenceNumber"] == "5"
 | 
				
			||||||
    resp["Records"][0]["PartitionKey"].should.equal("last_record")
 | 
					    assert resp["Records"][0]["PartitionKey"] == "last_record"
 | 
				
			||||||
    resp["Records"][0]["Data"].should.equal(b"last_record")
 | 
					    assert resp["Records"][0]["Data"] == b"last_record"
 | 
				
			||||||
    resp["MillisBehindLatest"].should.equal(0)
 | 
					    assert resp["MillisBehindLatest"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -428,10 +425,10 @@ def test_get_records_at_timestamp():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    response = conn.get_records(ShardIterator=shard_iterator)
 | 
					    response = conn.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response["Records"].should.have.length_of(len(keys))
 | 
					    assert len(response["Records"]) == len(keys)
 | 
				
			||||||
    partition_keys = [r["PartitionKey"] for r in response["Records"]]
 | 
					    partition_keys = [r["PartitionKey"] for r in response["Records"]]
 | 
				
			||||||
    partition_keys.should.equal(keys)
 | 
					    assert partition_keys == keys
 | 
				
			||||||
    response["MillisBehindLatest"].should.equal(0)
 | 
					    assert response["MillisBehindLatest"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -457,10 +454,10 @@ def test_get_records_at_very_old_timestamp():
 | 
				
			|||||||
    shard_iterator = response["ShardIterator"]
 | 
					    shard_iterator = response["ShardIterator"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = conn.get_records(ShardIterator=shard_iterator)
 | 
					    response = conn.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
    response["Records"].should.have.length_of(len(keys))
 | 
					    assert len(response["Records"]) == len(keys)
 | 
				
			||||||
    partition_keys = [r["PartitionKey"] for r in response["Records"]]
 | 
					    partition_keys = [r["PartitionKey"] for r in response["Records"]]
 | 
				
			||||||
    partition_keys.should.equal(keys)
 | 
					    assert partition_keys == keys
 | 
				
			||||||
    response["MillisBehindLatest"].should.equal(0)
 | 
					    assert response["MillisBehindLatest"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -487,12 +484,10 @@ def test_get_records_timestamp_filtering():
 | 
				
			|||||||
    shard_iterator = response["ShardIterator"]
 | 
					    shard_iterator = response["ShardIterator"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = conn.get_records(ShardIterator=shard_iterator)
 | 
					    response = conn.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
    response["Records"].should.have.length_of(1)
 | 
					    assert len(response["Records"]) == 1
 | 
				
			||||||
    response["Records"][0]["PartitionKey"].should.equal("1")
 | 
					    assert response["Records"][0]["PartitionKey"] == "1"
 | 
				
			||||||
    response["Records"][0]["ApproximateArrivalTimestamp"].should.be.greater_than(
 | 
					    assert response["Records"][0]["ApproximateArrivalTimestamp"] > timestamp
 | 
				
			||||||
        timestamp
 | 
					    assert response["MillisBehindLatest"] == 0
 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    response["MillisBehindLatest"].should.equal(0)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -513,8 +508,8 @@ def test_get_records_millis_behind_latest():
 | 
				
			|||||||
    shard_iterator = response["ShardIterator"]
 | 
					    shard_iterator = response["ShardIterator"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = conn.get_records(ShardIterator=shard_iterator, Limit=1)
 | 
					    response = conn.get_records(ShardIterator=shard_iterator, Limit=1)
 | 
				
			||||||
    response["Records"].should.have.length_of(1)
 | 
					    assert len(response["Records"]) == 1
 | 
				
			||||||
    response["MillisBehindLatest"].should.be.greater_than(0)
 | 
					    assert response["MillisBehindLatest"] > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -543,8 +538,8 @@ def test_get_records_at_very_new_timestamp():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    response = conn.get_records(ShardIterator=shard_iterator)
 | 
					    response = conn.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response["Records"].should.have.length_of(0)
 | 
					    assert len(response["Records"]) == 0
 | 
				
			||||||
    response["MillisBehindLatest"].should.equal(0)
 | 
					    assert response["MillisBehindLatest"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -568,8 +563,8 @@ def test_get_records_from_empty_stream_at_timestamp():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    response = conn.get_records(ShardIterator=shard_iterator)
 | 
					    response = conn.get_records(ShardIterator=shard_iterator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response["Records"].should.have.length_of(0)
 | 
					    assert len(response["Records"]) == 0
 | 
				
			||||||
    response["MillisBehindLatest"].should.equal(0)
 | 
					    assert response["MillisBehindLatest"] == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -583,7 +578,7 @@ def test_valid_increase_stream_retention_period():
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = conn.describe_stream(StreamName=stream_name)
 | 
					    response = conn.describe_stream(StreamName=stream_name)
 | 
				
			||||||
    response["StreamDescription"]["RetentionPeriodHours"].should.equal(40)
 | 
					    assert response["StreamDescription"]["RetentionPeriodHours"] == 40
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -599,9 +594,10 @@ def test_invalid_increase_stream_retention_period():
 | 
				
			|||||||
        conn.increase_stream_retention_period(
 | 
					        conn.increase_stream_retention_period(
 | 
				
			||||||
            StreamName=stream_name, RetentionPeriodHours=25
 | 
					            StreamName=stream_name, RetentionPeriodHours=25
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    ex.value.response["Error"]["Code"].should.equal("InvalidArgumentException")
 | 
					    assert ex.value.response["Error"]["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    ex.value.response["Error"]["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "Requested retention period (25 hours) for stream my_stream can not be shorter than existing retention period (30 hours). Use DecreaseRetentionPeriod API."
 | 
					        ex.value.response["Error"]["Message"]
 | 
				
			||||||
 | 
					        == "Requested retention period (25 hours) for stream my_stream can not be shorter than existing retention period (30 hours). Use DecreaseRetentionPeriod API."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -616,9 +612,10 @@ def test_invalid_increase_stream_retention_too_low():
 | 
				
			|||||||
            StreamName=stream_name, RetentionPeriodHours=20
 | 
					            StreamName=stream_name, RetentionPeriodHours=20
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = ex.value.response["Error"]
 | 
					    err = ex.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "Minimum allowed retention period is 24 hours. Requested retention period (20 hours) is too short."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "Minimum allowed retention period is 24 hours. Requested retention period (20 hours) is too short."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -633,9 +630,10 @@ def test_invalid_increase_stream_retention_too_high():
 | 
				
			|||||||
            StreamName=stream_name, RetentionPeriodHours=9999
 | 
					            StreamName=stream_name, RetentionPeriodHours=9999
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = ex.value.response["Error"]
 | 
					    err = ex.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "Maximum allowed retention period is 8760 hours. Requested retention period (9999 hours) is too long."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "Maximum allowed retention period is 8760 hours. Requested retention period (9999 hours) is too long."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -654,13 +652,13 @@ def test_valid_decrease_stream_retention_period():
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = conn.describe_stream(StreamName=stream_name)
 | 
					    response = conn.describe_stream(StreamName=stream_name)
 | 
				
			||||||
    response["StreamDescription"]["RetentionPeriodHours"].should.equal(25)
 | 
					    assert response["StreamDescription"]["RetentionPeriodHours"] == 25
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    conn.increase_stream_retention_period(StreamARN=stream_arn, RetentionPeriodHours=29)
 | 
					    conn.increase_stream_retention_period(StreamARN=stream_arn, RetentionPeriodHours=29)
 | 
				
			||||||
    conn.decrease_stream_retention_period(StreamARN=stream_arn, RetentionPeriodHours=26)
 | 
					    conn.decrease_stream_retention_period(StreamARN=stream_arn, RetentionPeriodHours=26)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = conn.describe_stream(StreamARN=stream_arn)
 | 
					    response = conn.describe_stream(StreamARN=stream_arn)
 | 
				
			||||||
    response["StreamDescription"]["RetentionPeriodHours"].should.equal(26)
 | 
					    assert response["StreamDescription"]["RetentionPeriodHours"] == 26
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -674,9 +672,10 @@ def test_decrease_stream_retention_period_upwards():
 | 
				
			|||||||
            StreamName=stream_name, RetentionPeriodHours=40
 | 
					            StreamName=stream_name, RetentionPeriodHours=40
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = ex.value.response["Error"]
 | 
					    err = ex.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "Requested retention period (40 hours) for stream decrease_stream can not be longer than existing retention period (24 hours). Use IncreaseRetentionPeriod API."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "Requested retention period (40 hours) for stream decrease_stream can not be longer than existing retention period (24 hours). Use IncreaseRetentionPeriod API."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -691,9 +690,10 @@ def test_decrease_stream_retention_period_too_low():
 | 
				
			|||||||
            StreamName=stream_name, RetentionPeriodHours=4
 | 
					            StreamName=stream_name, RetentionPeriodHours=4
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = ex.value.response["Error"]
 | 
					    err = ex.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "Minimum allowed retention period is 24 hours. Requested retention period (4 hours) is too short."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "Minimum allowed retention period is 24 hours. Requested retention period (4 hours) is too short."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -708,9 +708,10 @@ def test_decrease_stream_retention_period_too_high():
 | 
				
			|||||||
            StreamName=stream_name, RetentionPeriodHours=9999
 | 
					            StreamName=stream_name, RetentionPeriodHours=9999
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = ex.value.response["Error"]
 | 
					    err = ex.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "Maximum allowed retention period is 8760 hours. Requested retention period (9999 hours) is too long."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "Maximum allowed retention period is 8760 hours. Requested retention period (9999 hours) is too long."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -727,8 +728,8 @@ def test_invalid_shard_iterator_type():
 | 
				
			|||||||
            StreamName=stream_name, ShardId=shard_id, ShardIteratorType="invalid-type"
 | 
					            StreamName=stream_name, ShardId=shard_id, ShardIteratorType="invalid-type"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal("Invalid ShardIteratorType: invalid-type")
 | 
					    assert err["Message"] == "Invalid ShardIteratorType: invalid-type"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -743,32 +744,32 @@ def test_add_list_remove_tags():
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tags = client.list_tags_for_stream(StreamName=stream_name)["Tags"]
 | 
					    tags = client.list_tags_for_stream(StreamName=stream_name)["Tags"]
 | 
				
			||||||
    tags.should.have.length_of(4)
 | 
					    assert len(tags) == 4
 | 
				
			||||||
    tags.should.contain({"Key": "tag1", "Value": "val1"})
 | 
					    assert {"Key": "tag1", "Value": "val1"} in tags
 | 
				
			||||||
    tags.should.contain({"Key": "tag2", "Value": "val2"})
 | 
					    assert {"Key": "tag2", "Value": "val2"} in tags
 | 
				
			||||||
    tags.should.contain({"Key": "tag3", "Value": "val3"})
 | 
					    assert {"Key": "tag3", "Value": "val3"} in tags
 | 
				
			||||||
    tags.should.contain({"Key": "tag4", "Value": "val4"})
 | 
					    assert {"Key": "tag4", "Value": "val4"} in tags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.add_tags_to_stream(StreamARN=stream_arn, Tags={"tag5": "val5"})
 | 
					    client.add_tags_to_stream(StreamARN=stream_arn, Tags={"tag5": "val5"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tags = client.list_tags_for_stream(StreamARN=stream_arn)["Tags"]
 | 
					    tags = client.list_tags_for_stream(StreamARN=stream_arn)["Tags"]
 | 
				
			||||||
    tags.should.have.length_of(5)
 | 
					    assert len(tags) == 5
 | 
				
			||||||
    tags.should.contain({"Key": "tag5", "Value": "val5"})
 | 
					    assert {"Key": "tag5", "Value": "val5"} in tags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.remove_tags_from_stream(StreamName=stream_name, TagKeys=["tag2", "tag3"])
 | 
					    client.remove_tags_from_stream(StreamName=stream_name, TagKeys=["tag2", "tag3"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tags = client.list_tags_for_stream(StreamName=stream_name)["Tags"]
 | 
					    tags = client.list_tags_for_stream(StreamName=stream_name)["Tags"]
 | 
				
			||||||
    tags.should.have.length_of(3)
 | 
					    assert len(tags) == 3
 | 
				
			||||||
    tags.should.contain({"Key": "tag1", "Value": "val1"})
 | 
					    assert {"Key": "tag1", "Value": "val1"} in tags
 | 
				
			||||||
    tags.should.contain({"Key": "tag4", "Value": "val4"})
 | 
					    assert {"Key": "tag4", "Value": "val4"} in tags
 | 
				
			||||||
    tags.should.contain({"Key": "tag5", "Value": "val5"})
 | 
					    assert {"Key": "tag5", "Value": "val5"} in tags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.remove_tags_from_stream(StreamARN=stream_arn, TagKeys=["tag4"])
 | 
					    client.remove_tags_from_stream(StreamARN=stream_arn, TagKeys=["tag4"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tags = client.list_tags_for_stream(StreamName=stream_name)["Tags"]
 | 
					    tags = client.list_tags_for_stream(StreamName=stream_name)["Tags"]
 | 
				
			||||||
    tags.should.have.length_of(2)
 | 
					    assert len(tags) == 2
 | 
				
			||||||
    tags.should.contain({"Key": "tag1", "Value": "val1"})
 | 
					    assert {"Key": "tag1", "Value": "val1"} in tags
 | 
				
			||||||
    tags.should.contain({"Key": "tag5", "Value": "val5"})
 | 
					    assert {"Key": "tag5", "Value": "val5"} in tags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -793,7 +794,7 @@ def test_merge_shards():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
					    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
				
			||||||
    shards = stream["Shards"]
 | 
					    shards = stream["Shards"]
 | 
				
			||||||
    shards.should.have.length_of(4)
 | 
					    assert len(shards) == 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.merge_shards(
 | 
					    client.merge_shards(
 | 
				
			||||||
        StreamName=stream_name,
 | 
					        StreamName=stream_name,
 | 
				
			||||||
@ -805,7 +806,7 @@ def test_merge_shards():
 | 
				
			|||||||
    shards = stream["Shards"]
 | 
					    shards = stream["Shards"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Old shards still exist, but are closed. A new shard is created out of the old one
 | 
					    # Old shards still exist, but are closed. A new shard is created out of the old one
 | 
				
			||||||
    shards.should.have.length_of(5)
 | 
					    assert len(shards) == 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Only three shards are active - the two merged shards are closed
 | 
					    # Only three shards are active - the two merged shards are closed
 | 
				
			||||||
    active_shards = [
 | 
					    active_shards = [
 | 
				
			||||||
@ -813,7 +814,7 @@ def test_merge_shards():
 | 
				
			|||||||
        for shard in shards
 | 
					        for shard in shards
 | 
				
			||||||
        if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
					        if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    active_shards.should.have.length_of(3)
 | 
					    assert len(active_shards) == 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.merge_shards(
 | 
					    client.merge_shards(
 | 
				
			||||||
        StreamARN=stream_arn,
 | 
					        StreamARN=stream_arn,
 | 
				
			||||||
@ -829,23 +830,21 @@ def test_merge_shards():
 | 
				
			|||||||
        for shard in shards
 | 
					        for shard in shards
 | 
				
			||||||
        if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
					        if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    active_shards.should.have.length_of(2)
 | 
					    assert len(active_shards) == 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for shard in active_shards:
 | 
					    for shard in active_shards:
 | 
				
			||||||
        del shard["HashKeyRange"]
 | 
					        del shard["HashKeyRange"]
 | 
				
			||||||
        del shard["SequenceNumberRange"]
 | 
					        del shard["SequenceNumberRange"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Original shard #3 is still active (0,1,2 have been merged and closed
 | 
					    # Original shard #3 is still active (0,1,2 have been merged and closed
 | 
				
			||||||
    active_shards.should.contain({"ShardId": "shardId-000000000003"})
 | 
					    assert {"ShardId": "shardId-000000000003"} in active_shards
 | 
				
			||||||
    # Shard #4 was the child of #0 and #1
 | 
					    # Shard #4 was the child of #0 and #1
 | 
				
			||||||
    # Shard #5 is the child of #4 (parent) and #2 (adjacent-parent)
 | 
					    # Shard #5 is the child of #4 (parent) and #2 (adjacent-parent)
 | 
				
			||||||
    active_shards.should.contain(
 | 
					    assert {
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
        "ShardId": "shardId-000000000005",
 | 
					        "ShardId": "shardId-000000000005",
 | 
				
			||||||
        "ParentShardId": "shardId-000000000004",
 | 
					        "ParentShardId": "shardId-000000000004",
 | 
				
			||||||
        "AdjacentParentShardId": "shardId-000000000002",
 | 
					        "AdjacentParentShardId": "shardId-000000000002",
 | 
				
			||||||
        }
 | 
					    } in active_shards
 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -861,8 +860,8 @@ def test_merge_shards_invalid_arg():
 | 
				
			|||||||
            AdjacentShardToMerge="shardId-000000000002",
 | 
					            AdjacentShardToMerge="shardId-000000000002",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal("shardId-000000000002")
 | 
					    assert err["Message"] == "shardId-000000000002"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_stream_arn(client, stream_name):
 | 
					def get_stream_arn(client, stream_name):
 | 
				
			||||||
 | 
				
			|||||||
@ -6,8 +6,6 @@ from moto import mock_kinesis
 | 
				
			|||||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
 | 
					from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
 | 
				
			||||||
from .test_kinesis import get_stream_arn
 | 
					from .test_kinesis import get_stream_arn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sure  # noqa # pylint: disable=unused-import
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
def test_describe_stream_limit_parameter():
 | 
					def test_describe_stream_limit_parameter():
 | 
				
			||||||
@ -17,26 +15,26 @@ def test_describe_stream_limit_parameter():
 | 
				
			|||||||
    client.create_stream(StreamName=stream_name, ShardCount=5)
 | 
					    client.create_stream(StreamName=stream_name, ShardCount=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    without_filter = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
					    without_filter = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
				
			||||||
    without_filter["Shards"].should.have.length_of(5)
 | 
					    assert len(without_filter["Shards"]) == 5
 | 
				
			||||||
    without_filter["HasMoreShards"].should.equal(False)
 | 
					    assert without_filter["HasMoreShards"] is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with_filter = client.describe_stream(StreamName=stream_name, Limit=2)[
 | 
					    with_filter = client.describe_stream(StreamName=stream_name, Limit=2)[
 | 
				
			||||||
        "StreamDescription"
 | 
					        "StreamDescription"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    with_filter["Shards"].should.have.length_of(2)
 | 
					    assert len(with_filter["Shards"]) == 2
 | 
				
			||||||
    with_filter["HasMoreShards"].should.equal(True)
 | 
					    assert with_filter["HasMoreShards"] is True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with_filter = client.describe_stream(StreamName=stream_name, Limit=5)[
 | 
					    with_filter = client.describe_stream(StreamName=stream_name, Limit=5)[
 | 
				
			||||||
        "StreamDescription"
 | 
					        "StreamDescription"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    with_filter["Shards"].should.have.length_of(5)
 | 
					    assert len(with_filter["Shards"]) == 5
 | 
				
			||||||
    with_filter["HasMoreShards"].should.equal(False)
 | 
					    assert with_filter["HasMoreShards"] is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    with_filter = client.describe_stream(StreamName=stream_name, Limit=6)[
 | 
					    with_filter = client.describe_stream(StreamName=stream_name, Limit=6)[
 | 
				
			||||||
        "StreamDescription"
 | 
					        "StreamDescription"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    with_filter["Shards"].should.have.length_of(5)
 | 
					    assert len(with_filter["Shards"]) == 5
 | 
				
			||||||
    with_filter["HasMoreShards"].should.equal(False)
 | 
					    assert with_filter["HasMoreShards"] is False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -53,23 +51,24 @@ def test_list_shards():
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shard_list = conn.list_shards(StreamName=stream_name)["Shards"]
 | 
					    shard_list = conn.list_shards(StreamName=stream_name)["Shards"]
 | 
				
			||||||
    shard_list.should.have.length_of(2)
 | 
					    assert len(shard_list) == 2
 | 
				
			||||||
    # Verify IDs
 | 
					    # Verify IDs
 | 
				
			||||||
    [s["ShardId"] for s in shard_list].should.equal(
 | 
					    assert [s["ShardId"] for s in shard_list] == [
 | 
				
			||||||
        ["shardId-000000000000", "shardId-000000000001"]
 | 
					        "shardId-000000000000",
 | 
				
			||||||
    )
 | 
					        "shardId-000000000001",
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
    # Verify hash range
 | 
					    # Verify hash range
 | 
				
			||||||
    for shard in shard_list:
 | 
					    for shard in shard_list:
 | 
				
			||||||
        shard.should.have.key("HashKeyRange")
 | 
					        assert "HashKeyRange" in shard
 | 
				
			||||||
        shard["HashKeyRange"].should.have.key("StartingHashKey")
 | 
					        assert "StartingHashKey" in shard["HashKeyRange"]
 | 
				
			||||||
        shard["HashKeyRange"].should.have.key("EndingHashKey")
 | 
					        assert "EndingHashKey" in shard["HashKeyRange"]
 | 
				
			||||||
    shard_list[0]["HashKeyRange"]["EndingHashKey"].should.equal(
 | 
					    assert shard_list[0]["HashKeyRange"]["EndingHashKey"] == str(
 | 
				
			||||||
        str(int(shard_list[1]["HashKeyRange"]["StartingHashKey"]) - 1)
 | 
					        int(shard_list[1]["HashKeyRange"]["StartingHashKey"]) - 1
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    # Verify sequence numbers
 | 
					    # Verify sequence numbers
 | 
				
			||||||
    for shard in shard_list:
 | 
					    for shard in shard_list:
 | 
				
			||||||
        shard.should.have.key("SequenceNumberRange")
 | 
					        assert "SequenceNumberRange" in shard
 | 
				
			||||||
        shard["SequenceNumberRange"].should.have.key("StartingSequenceNumber")
 | 
					        assert "StartingSequenceNumber" in shard["SequenceNumberRange"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -80,46 +79,43 @@ def test_list_shards_paging():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # Get shard 1-10
 | 
					    # Get shard 1-10
 | 
				
			||||||
    shard_list = client.list_shards(StreamName=stream_name)
 | 
					    shard_list = client.list_shards(StreamName=stream_name)
 | 
				
			||||||
    shard_list["Shards"].should.have.length_of(10)
 | 
					    assert len(shard_list["Shards"]) == 10
 | 
				
			||||||
    shard_list.should_not.have.key("NextToken")
 | 
					    assert "NextToken" not in shard_list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Get shard 1-4
 | 
					    # Get shard 1-4
 | 
				
			||||||
    resp = client.list_shards(StreamName=stream_name, MaxResults=4)
 | 
					    resp = client.list_shards(StreamName=stream_name, MaxResults=4)
 | 
				
			||||||
    resp["Shards"].should.have.length_of(4)
 | 
					    assert len(resp["Shards"]) == 4
 | 
				
			||||||
    [s["ShardId"] for s in resp["Shards"]].should.equal(
 | 
					    assert [s["ShardId"] for s in resp["Shards"]] == [
 | 
				
			||||||
        [
 | 
					 | 
				
			||||||
        "shardId-000000000000",
 | 
					        "shardId-000000000000",
 | 
				
			||||||
        "shardId-000000000001",
 | 
					        "shardId-000000000001",
 | 
				
			||||||
        "shardId-000000000002",
 | 
					        "shardId-000000000002",
 | 
				
			||||||
        "shardId-000000000003",
 | 
					        "shardId-000000000003",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    )
 | 
					    assert "NextToken" in resp
 | 
				
			||||||
    resp.should.have.key("NextToken")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Get shard 4-8
 | 
					    # Get shard 4-8
 | 
				
			||||||
    resp = client.list_shards(
 | 
					    resp = client.list_shards(
 | 
				
			||||||
        StreamName=stream_name, MaxResults=4, NextToken=str(resp["NextToken"])
 | 
					        StreamName=stream_name, MaxResults=4, NextToken=str(resp["NextToken"])
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    resp["Shards"].should.have.length_of(4)
 | 
					    assert len(resp["Shards"]) == 4
 | 
				
			||||||
    [s["ShardId"] for s in resp["Shards"]].should.equal(
 | 
					    assert [s["ShardId"] for s in resp["Shards"]] == [
 | 
				
			||||||
        [
 | 
					 | 
				
			||||||
        "shardId-000000000004",
 | 
					        "shardId-000000000004",
 | 
				
			||||||
        "shardId-000000000005",
 | 
					        "shardId-000000000005",
 | 
				
			||||||
        "shardId-000000000006",
 | 
					        "shardId-000000000006",
 | 
				
			||||||
        "shardId-000000000007",
 | 
					        "shardId-000000000007",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    )
 | 
					    assert "NextToken" in resp
 | 
				
			||||||
    resp.should.have.key("NextToken")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Get shard 8-10
 | 
					    # Get shard 8-10
 | 
				
			||||||
    resp = client.list_shards(
 | 
					    resp = client.list_shards(
 | 
				
			||||||
        StreamName=stream_name, MaxResults=4, NextToken=str(resp["NextToken"])
 | 
					        StreamName=stream_name, MaxResults=4, NextToken=str(resp["NextToken"])
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    resp["Shards"].should.have.length_of(2)
 | 
					    assert len(resp["Shards"]) == 2
 | 
				
			||||||
    [s["ShardId"] for s in resp["Shards"]].should.equal(
 | 
					    assert [s["ShardId"] for s in resp["Shards"]] == [
 | 
				
			||||||
        ["shardId-000000000008", "shardId-000000000009"]
 | 
					        "shardId-000000000008",
 | 
				
			||||||
    )
 | 
					        "shardId-000000000009",
 | 
				
			||||||
    resp.should_not.have.key("NextToken")
 | 
					    ]
 | 
				
			||||||
 | 
					    assert "NextToken" not in resp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -129,26 +125,26 @@ def test_create_shard():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream(StreamName="my-stream")
 | 
					    resp = client.describe_stream(StreamName="my-stream")
 | 
				
			||||||
    desc = resp["StreamDescription"]
 | 
					    desc = resp["StreamDescription"]
 | 
				
			||||||
    desc.should.have.key("StreamName").equal("my-stream")
 | 
					    assert desc["StreamName"] == "my-stream"
 | 
				
			||||||
    desc.should.have.key("StreamARN").equal(
 | 
					    assert (
 | 
				
			||||||
        f"arn:aws:kinesis:us-west-2:{ACCOUNT_ID}:stream/my-stream"
 | 
					        desc["StreamARN"] == f"arn:aws:kinesis:us-west-2:{ACCOUNT_ID}:stream/my-stream"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    desc.should.have.key("Shards").length_of(2)
 | 
					    assert len(desc["Shards"]) == 2
 | 
				
			||||||
    desc.should.have.key("StreamStatus").equals("ACTIVE")
 | 
					    assert desc["StreamStatus"] == "ACTIVE"
 | 
				
			||||||
    desc.should.have.key("HasMoreShards").equals(False)
 | 
					    assert desc["HasMoreShards"] is False
 | 
				
			||||||
    desc.should.have.key("RetentionPeriodHours").equals(24)
 | 
					    assert desc["RetentionPeriodHours"] == 24
 | 
				
			||||||
    desc.should.have.key("StreamCreationTimestamp")
 | 
					    assert "StreamCreationTimestamp" in desc
 | 
				
			||||||
    desc.should.have.key("EnhancedMonitoring").should.equal([{"ShardLevelMetrics": []}])
 | 
					    assert desc["EnhancedMonitoring"] == [{"ShardLevelMetrics": []}]
 | 
				
			||||||
    desc.should.have.key("EncryptionType").should.equal("NONE")
 | 
					    assert desc["EncryptionType"] == "NONE"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shards = desc["Shards"]
 | 
					    shards = desc["Shards"]
 | 
				
			||||||
    shards[0].should.have.key("ShardId").equal("shardId-000000000000")
 | 
					    assert shards[0]["ShardId"] == "shardId-000000000000"
 | 
				
			||||||
    shards[0].should.have.key("HashKeyRange")
 | 
					    assert "HashKeyRange" in shards[0]
 | 
				
			||||||
    shards[0]["HashKeyRange"].should.have.key("StartingHashKey").equals("0")
 | 
					    assert shards[0]["HashKeyRange"]["StartingHashKey"] == "0"
 | 
				
			||||||
    shards[0]["HashKeyRange"].should.have.key("EndingHashKey")
 | 
					    assert "EndingHashKey" in shards[0]["HashKeyRange"]
 | 
				
			||||||
    shards[0].should.have.key("SequenceNumberRange")
 | 
					    assert "SequenceNumberRange" in shards[0]
 | 
				
			||||||
    shards[0]["SequenceNumberRange"].should.have.key("StartingSequenceNumber")
 | 
					    assert "StartingSequenceNumber" in shards[0]["SequenceNumberRange"]
 | 
				
			||||||
    shards[0]["SequenceNumberRange"].shouldnt.have.key("EndingSequenceNumber")
 | 
					    assert "EndingSequenceNumber" not in shards[0]["SequenceNumberRange"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -163,9 +159,10 @@ def test_split_shard_with_invalid_name():
 | 
				
			|||||||
            NewStartingHashKey="170141183460469231731687303715884105728",
 | 
					            NewStartingHashKey="170141183460469231731687303715884105728",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ValidationException")
 | 
					    assert err["Code"] == "ValidationException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "1 validation error detected: Value '?' at 'shardToSplit' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-zA-Z0-9_.-]+"
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "1 validation error detected: Value '?' at 'shardToSplit' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-zA-Z0-9_.-]+"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -181,9 +178,10 @@ def test_split_shard_with_unknown_name():
 | 
				
			|||||||
            NewStartingHashKey="170141183460469231731687303715884105728",
 | 
					            NewStartingHashKey="170141183460469231731687303715884105728",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ResourceNotFoundException")
 | 
					    assert err["Code"] == "ResourceNotFoundException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "Could not find shard unknown in stream my-stream under account 123456789012."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "Could not find shard unknown in stream my-stream under account 123456789012."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -199,9 +197,10 @@ def test_split_shard_invalid_hashkey():
 | 
				
			|||||||
            NewStartingHashKey="sth",
 | 
					            NewStartingHashKey="sth",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ValidationException")
 | 
					    assert err["Code"] == "ValidationException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "1 validation error detected: Value 'sth' at 'newStartingHashKey' failed to satisfy constraint: Member must satisfy regular expression pattern: 0|([1-9]\\d{0,38})"
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "1 validation error detected: Value 'sth' at 'newStartingHashKey' failed to satisfy constraint: Member must satisfy regular expression pattern: 0|([1-9]\\d{0,38})"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -217,9 +216,10 @@ def test_split_shard_hashkey_out_of_bounds():
 | 
				
			|||||||
            NewStartingHashKey="170141183460469231731687303715884000000",
 | 
					            NewStartingHashKey="170141183460469231731687303715884000000",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        f"NewStartingHashKey 170141183460469231731687303715884000000 used in SplitShard() on shard shardId-000000000001 in stream my-stream under account {ACCOUNT_ID} is not both greater than one plus the shard's StartingHashKey 170141183460469231731687303715884105728 and less than the shard's EndingHashKey 340282366920938463463374607431768211455."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == f"NewStartingHashKey 170141183460469231731687303715884000000 used in SplitShard() on shard shardId-000000000001 in stream my-stream under account {ACCOUNT_ID} is not both greater than one plus the shard's StartingHashKey 170141183460469231731687303715884105728 and less than the shard's EndingHashKey 340282366920938463463374607431768211455."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -248,32 +248,34 @@ def test_split_shard():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
					    resp = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
				
			||||||
    shards = resp["Shards"]
 | 
					    shards = resp["Shards"]
 | 
				
			||||||
    shards.should.have.length_of(4)
 | 
					    assert len(shards) == 4
 | 
				
			||||||
    shards[0].should.have.key("ShardId").equals("shardId-000000000000")
 | 
					    assert shards[0]["ShardId"] == "shardId-000000000000"
 | 
				
			||||||
    shards[0].should.have.key("HashKeyRange")
 | 
					    assert "HashKeyRange" in shards[0]
 | 
				
			||||||
    shards[0].shouldnt.have.key("ParentShardId")
 | 
					    assert "ParentShardId" not in shards[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shards[1].should.have.key("ShardId").equals("shardId-000000000001")
 | 
					    assert shards[1]["ShardId"] == "shardId-000000000001"
 | 
				
			||||||
    shards[1].shouldnt.have.key("ParentShardId")
 | 
					    assert "ParentShardId" not in shards[1]
 | 
				
			||||||
    shards[1].should.have.key("HashKeyRange")
 | 
					    assert "HashKeyRange" in shards[1]
 | 
				
			||||||
    shards[1]["HashKeyRange"].should.have.key("StartingHashKey").equals(
 | 
					    assert (
 | 
				
			||||||
        original_shards[1]["HashKeyRange"]["StartingHashKey"]
 | 
					        shards[1]["HashKeyRange"]["StartingHashKey"]
 | 
				
			||||||
 | 
					        == original_shards[1]["HashKeyRange"]["StartingHashKey"]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    shards[1]["HashKeyRange"].should.have.key("EndingHashKey").equals(
 | 
					    assert (
 | 
				
			||||||
        original_shards[1]["HashKeyRange"]["EndingHashKey"]
 | 
					        shards[1]["HashKeyRange"]["EndingHashKey"]
 | 
				
			||||||
 | 
					        == original_shards[1]["HashKeyRange"]["EndingHashKey"]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    shards[1]["SequenceNumberRange"].should.have.key("StartingSequenceNumber")
 | 
					    assert "StartingSequenceNumber" in shards[1]["SequenceNumberRange"]
 | 
				
			||||||
    shards[1]["SequenceNumberRange"].should.have.key("EndingSequenceNumber")
 | 
					    assert "EndingSequenceNumber" in shards[1]["SequenceNumberRange"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shards[2].should.have.key("ShardId").equals("shardId-000000000002")
 | 
					    assert shards[2]["ShardId"] == "shardId-000000000002"
 | 
				
			||||||
    shards[2].should.have.key("ParentShardId").equals(shards[1]["ShardId"])
 | 
					    assert shards[2]["ParentShardId"] == shards[1]["ShardId"]
 | 
				
			||||||
    shards[2]["SequenceNumberRange"].should.have.key("StartingSequenceNumber")
 | 
					    assert "StartingSequenceNumber" in shards[2]["SequenceNumberRange"]
 | 
				
			||||||
    shards[2]["SequenceNumberRange"].shouldnt.have.key("EndingSequenceNumber")
 | 
					    assert "EndingSequenceNumber" not in shards[2]["SequenceNumberRange"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shards[3].should.have.key("ShardId").equals("shardId-000000000003")
 | 
					    assert shards[3]["ShardId"] == "shardId-000000000003"
 | 
				
			||||||
    shards[3].should.have.key("ParentShardId").equals(shards[1]["ShardId"])
 | 
					    assert shards[3]["ParentShardId"] == shards[1]["ShardId"]
 | 
				
			||||||
    shards[3]["SequenceNumberRange"].should.have.key("StartingSequenceNumber")
 | 
					    assert "StartingSequenceNumber" in shards[3]["SequenceNumberRange"]
 | 
				
			||||||
    shards[3]["SequenceNumberRange"].shouldnt.have.key("EndingSequenceNumber")
 | 
					    assert "EndingSequenceNumber" not in shards[3]["SequenceNumberRange"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -295,9 +297,10 @@ def test_split_shard_that_was_split_before():
 | 
				
			|||||||
            NewStartingHashKey="170141183460469231731687303715884105829",
 | 
					            NewStartingHashKey="170141183460469231731687303715884105829",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        f"Shard shardId-000000000001 in stream my-stream under account {ACCOUNT_ID} has already been merged or split, and thus is not eligible for merging or splitting."
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == f"Shard shardId-000000000001 in stream my-stream under account {ACCOUNT_ID} has already been merged or split, and thus is not eligible for merging or splitting."
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -322,22 +325,22 @@ def test_update_shard_count(initial, target, expected_total):
 | 
				
			|||||||
        StreamName="my-stream", TargetShardCount=target, ScalingType="UNIFORM_SCALING"
 | 
					        StreamName="my-stream", TargetShardCount=target, ScalingType="UNIFORM_SCALING"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp.should.have.key("StreamName").equals("my-stream")
 | 
					    assert resp["StreamName"] == "my-stream"
 | 
				
			||||||
    resp.should.have.key("CurrentShardCount").equals(initial)
 | 
					    assert resp["CurrentShardCount"] == initial
 | 
				
			||||||
    resp.should.have.key("TargetShardCount").equals(target)
 | 
					    assert resp["TargetShardCount"] == target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream = client.describe_stream(StreamName="my-stream")["StreamDescription"]
 | 
					    stream = client.describe_stream(StreamName="my-stream")["StreamDescription"]
 | 
				
			||||||
    stream["StreamStatus"].should.equal("ACTIVE")
 | 
					    assert stream["StreamStatus"] == "ACTIVE"
 | 
				
			||||||
    stream["Shards"].should.have.length_of(expected_total)
 | 
					    assert len(stream["Shards"]) == expected_total
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    active_shards = [
 | 
					    active_shards = [
 | 
				
			||||||
        shard
 | 
					        shard
 | 
				
			||||||
        for shard in stream["Shards"]
 | 
					        for shard in stream["Shards"]
 | 
				
			||||||
        if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
					        if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    active_shards.should.have.length_of(target)
 | 
					    assert len(active_shards) == target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream_summary(StreamName="my-stream")
 | 
					    resp = client.describe_stream_summary(StreamName="my-stream")
 | 
				
			||||||
    stream = resp["StreamDescriptionSummary"]
 | 
					    stream = resp["StreamDescriptionSummary"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream["OpenShardCount"].should.equal(target)
 | 
					    assert stream["OpenShardCount"] == target
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,4 @@
 | 
				
			|||||||
import boto3
 | 
					import boto3
 | 
				
			||||||
import sure  # noqa # pylint: disable=unused-import
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from moto import mock_kinesis, mock_cloudformation
 | 
					from moto import mock_kinesis, mock_cloudformation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -17,8 +16,8 @@ def test_kinesis_cloudformation_create_stream():
 | 
				
			|||||||
    provisioned_resource = cf_conn.list_stack_resources(StackName=stack_name)[
 | 
					    provisioned_resource = cf_conn.list_stack_resources(StackName=stack_name)[
 | 
				
			||||||
        "StackResourceSummaries"
 | 
					        "StackResourceSummaries"
 | 
				
			||||||
    ][0]
 | 
					    ][0]
 | 
				
			||||||
    provisioned_resource["LogicalResourceId"].should.equal("MyStream")
 | 
					    assert provisioned_resource["LogicalResourceId"] == "MyStream"
 | 
				
			||||||
    len(provisioned_resource["PhysicalResourceId"]).should.be.greater_than(0)
 | 
					    assert len(provisioned_resource["PhysicalResourceId"]) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_cloudformation
 | 
					@mock_cloudformation
 | 
				
			||||||
@ -56,7 +55,7 @@ Outputs:
 | 
				
			|||||||
    stream_description = kinesis_conn.describe_stream(StreamName=output_stream_name)[
 | 
					    stream_description = kinesis_conn.describe_stream(StreamName=output_stream_name)[
 | 
				
			||||||
        "StreamDescription"
 | 
					        "StreamDescription"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    output_stream_arn.should.equal(stream_description["StreamARN"])
 | 
					    assert output_stream_arn == stream_description["StreamARN"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_cloudformation
 | 
					@mock_cloudformation
 | 
				
			||||||
@ -83,19 +82,19 @@ Resources:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    cf_conn.create_stack(StackName=stack_name, TemplateBody=template)
 | 
					    cf_conn.create_stack(StackName=stack_name, TemplateBody=template)
 | 
				
			||||||
    stack_description = cf_conn.describe_stacks(StackName=stack_name)["Stacks"][0]
 | 
					    stack_description = cf_conn.describe_stacks(StackName=stack_name)["Stacks"][0]
 | 
				
			||||||
    stack_description["StackName"].should.equal(stack_name)
 | 
					    assert stack_description["StackName"] == stack_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    kinesis_conn = boto3.client("kinesis", region_name="us-east-1")
 | 
					    kinesis_conn = boto3.client("kinesis", region_name="us-east-1")
 | 
				
			||||||
    stream_description = kinesis_conn.describe_stream(StreamName="MyStream")[
 | 
					    stream_description = kinesis_conn.describe_stream(StreamName="MyStream")[
 | 
				
			||||||
        "StreamDescription"
 | 
					        "StreamDescription"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    stream_description["RetentionPeriodHours"].should.equal(48)
 | 
					    assert stream_description["RetentionPeriodHours"] == 48
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tags = kinesis_conn.list_tags_for_stream(StreamName="MyStream")["Tags"]
 | 
					    tags = kinesis_conn.list_tags_for_stream(StreamName="MyStream")["Tags"]
 | 
				
			||||||
    tag1_value = [tag for tag in tags if tag["Key"] == "TagKey1"][0]["Value"]
 | 
					    tag1_value = [tag for tag in tags if tag["Key"] == "TagKey1"][0]["Value"]
 | 
				
			||||||
    tag2_value = [tag for tag in tags if tag["Key"] == "TagKey2"][0]["Value"]
 | 
					    tag2_value = [tag for tag in tags if tag["Key"] == "TagKey2"][0]["Value"]
 | 
				
			||||||
    tag1_value.should.equal("TagValue1")
 | 
					    assert tag1_value == "TagValue1"
 | 
				
			||||||
    tag2_value.should.equal("TagValue2")
 | 
					    assert tag2_value == "TagValue2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shards_provisioned = len(
 | 
					    shards_provisioned = len(
 | 
				
			||||||
        [
 | 
					        [
 | 
				
			||||||
@ -104,7 +103,7 @@ Resources:
 | 
				
			|||||||
            if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
					            if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    shards_provisioned.should.equal(4)
 | 
					    assert shards_provisioned == 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template = """
 | 
					    template = """
 | 
				
			||||||
    Resources:
 | 
					    Resources:
 | 
				
			||||||
@ -125,13 +124,13 @@ Resources:
 | 
				
			|||||||
    stream_description = kinesis_conn.describe_stream(StreamName="MyStream")[
 | 
					    stream_description = kinesis_conn.describe_stream(StreamName="MyStream")[
 | 
				
			||||||
        "StreamDescription"
 | 
					        "StreamDescription"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    stream_description["RetentionPeriodHours"].should.equal(24)
 | 
					    assert stream_description["RetentionPeriodHours"] == 24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tags = kinesis_conn.list_tags_for_stream(StreamName="MyStream")["Tags"]
 | 
					    tags = kinesis_conn.list_tags_for_stream(StreamName="MyStream")["Tags"]
 | 
				
			||||||
    tag1_value = [tag for tag in tags if tag["Key"] == "TagKey1"][0]["Value"]
 | 
					    tag1_value = [tag for tag in tags if tag["Key"] == "TagKey1"][0]["Value"]
 | 
				
			||||||
    tag2_value = [tag for tag in tags if tag["Key"] == "TagKey2"][0]["Value"]
 | 
					    tag2_value = [tag for tag in tags if tag["Key"] == "TagKey2"][0]["Value"]
 | 
				
			||||||
    tag1_value.should.equal("TagValue1a")
 | 
					    assert tag1_value == "TagValue1a"
 | 
				
			||||||
    tag2_value.should.equal("TagValue2a")
 | 
					    assert tag2_value == "TagValue2a"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    shards_provisioned = len(
 | 
					    shards_provisioned = len(
 | 
				
			||||||
        [
 | 
					        [
 | 
				
			||||||
@ -140,7 +139,7 @@ Resources:
 | 
				
			|||||||
            if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
					            if "EndingSequenceNumber" not in shard["SequenceNumberRange"]
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    shards_provisioned.should.equal(6)
 | 
					    assert shards_provisioned == 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_cloudformation
 | 
					@mock_cloudformation
 | 
				
			||||||
@ -160,14 +159,14 @@ Resources:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    cf_conn.create_stack(StackName=stack_name, TemplateBody=template)
 | 
					    cf_conn.create_stack(StackName=stack_name, TemplateBody=template)
 | 
				
			||||||
    stack_description = cf_conn.describe_stacks(StackName=stack_name)["Stacks"][0]
 | 
					    stack_description = cf_conn.describe_stacks(StackName=stack_name)["Stacks"][0]
 | 
				
			||||||
    stack_description["StackName"].should.equal(stack_name)
 | 
					    assert stack_description["StackName"] == stack_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    kinesis_conn = boto3.client("kinesis", region_name="us-east-1")
 | 
					    kinesis_conn = boto3.client("kinesis", region_name="us-east-1")
 | 
				
			||||||
    stream_description = kinesis_conn.describe_stream(StreamName="MyStream")[
 | 
					    stream_description = kinesis_conn.describe_stream(StreamName="MyStream")[
 | 
				
			||||||
        "StreamDescription"
 | 
					        "StreamDescription"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    stream_description["StreamName"].should.equal("MyStream")
 | 
					    assert stream_description["StreamName"] == "MyStream"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cf_conn.delete_stack(StackName=stack_name)
 | 
					    cf_conn.delete_stack(StackName=stack_name)
 | 
				
			||||||
    streams = kinesis_conn.list_streams()["StreamNames"]
 | 
					    streams = kinesis_conn.list_streams()["StreamNames"]
 | 
				
			||||||
    len(streams).should.equal(0)
 | 
					    assert len(streams) == 0
 | 
				
			||||||
 | 
				
			|||||||
@ -11,8 +11,8 @@ def test_enable_encryption():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream(StreamName="my-stream")
 | 
					    resp = client.describe_stream(StreamName="my-stream")
 | 
				
			||||||
    desc = resp["StreamDescription"]
 | 
					    desc = resp["StreamDescription"]
 | 
				
			||||||
    desc.should.have.key("EncryptionType").should.equal("NONE")
 | 
					    assert desc["EncryptionType"] == "NONE"
 | 
				
			||||||
    desc.shouldnt.have.key("KeyId")
 | 
					    assert "KeyId" not in desc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.start_stream_encryption(
 | 
					    client.start_stream_encryption(
 | 
				
			||||||
        StreamName="my-stream", EncryptionType="KMS", KeyId="n/a"
 | 
					        StreamName="my-stream", EncryptionType="KMS", KeyId="n/a"
 | 
				
			||||||
@ -20,8 +20,8 @@ def test_enable_encryption():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream(StreamName="my-stream")
 | 
					    resp = client.describe_stream(StreamName="my-stream")
 | 
				
			||||||
    desc = resp["StreamDescription"]
 | 
					    desc = resp["StreamDescription"]
 | 
				
			||||||
    desc.should.have.key("EncryptionType").should.equal("KMS")
 | 
					    assert desc["EncryptionType"] == "KMS"
 | 
				
			||||||
    desc.should.have.key("KeyId").equals("n/a")
 | 
					    assert desc["KeyId"] == "n/a"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -31,7 +31,7 @@ def test_disable_encryption():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream(StreamName="my-stream")
 | 
					    resp = client.describe_stream(StreamName="my-stream")
 | 
				
			||||||
    desc = resp["StreamDescription"]
 | 
					    desc = resp["StreamDescription"]
 | 
				
			||||||
    desc.should.have.key("EncryptionType").should.equal("NONE")
 | 
					    assert desc["EncryptionType"] == "NONE"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.start_stream_encryption(
 | 
					    client.start_stream_encryption(
 | 
				
			||||||
        StreamName="my-stream", EncryptionType="KMS", KeyId="n/a"
 | 
					        StreamName="my-stream", EncryptionType="KMS", KeyId="n/a"
 | 
				
			||||||
@ -43,8 +43,8 @@ def test_disable_encryption():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream(StreamName="my-stream")
 | 
					    resp = client.describe_stream(StreamName="my-stream")
 | 
				
			||||||
    desc = resp["StreamDescription"]
 | 
					    desc = resp["StreamDescription"]
 | 
				
			||||||
    desc.should.have.key("EncryptionType").should.equal("NONE")
 | 
					    assert desc["EncryptionType"] == "NONE"
 | 
				
			||||||
    desc.shouldnt.have.key("KeyId")
 | 
					    assert "KeyId" not in desc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -55,7 +55,7 @@ def test_disable_encryption__using_arns():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream(StreamName="my-stream")
 | 
					    resp = client.describe_stream(StreamName="my-stream")
 | 
				
			||||||
    desc = resp["StreamDescription"]
 | 
					    desc = resp["StreamDescription"]
 | 
				
			||||||
    desc.should.have.key("EncryptionType").should.equal("NONE")
 | 
					    assert desc["EncryptionType"] == "NONE"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.start_stream_encryption(
 | 
					    client.start_stream_encryption(
 | 
				
			||||||
        StreamARN=stream_arn, EncryptionType="KMS", KeyId="n/a"
 | 
					        StreamARN=stream_arn, EncryptionType="KMS", KeyId="n/a"
 | 
				
			||||||
@ -67,5 +67,5 @@ def test_disable_encryption__using_arns():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream(StreamName="my-stream")
 | 
					    resp = client.describe_stream(StreamName="my-stream")
 | 
				
			||||||
    desc = resp["StreamDescription"]
 | 
					    desc = resp["StreamDescription"]
 | 
				
			||||||
    desc.should.have.key("EncryptionType").should.equal("NONE")
 | 
					    assert desc["EncryptionType"] == "NONE"
 | 
				
			||||||
    desc.shouldnt.have.key("KeyId")
 | 
					    assert "KeyId" not in desc
 | 
				
			||||||
 | 
				
			|||||||
@ -15,11 +15,12 @@ def test_enable_enhanced_monitoring_all():
 | 
				
			|||||||
        StreamName=stream_name, ShardLevelMetrics=["ALL"]
 | 
					        StreamName=stream_name, ShardLevelMetrics=["ALL"]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp.should.have.key("StreamName").equals(stream_name)
 | 
					    assert resp["StreamName"] == stream_name
 | 
				
			||||||
    resp.should.have.key("CurrentShardLevelMetrics").equals([])
 | 
					    assert resp["CurrentShardLevelMetrics"] == []
 | 
				
			||||||
    resp.should.have.key("DesiredShardLevelMetrics").equals(["ALL"])
 | 
					    assert resp["DesiredShardLevelMetrics"] == ["ALL"]
 | 
				
			||||||
    resp.should.have.key("StreamARN").equals(
 | 
					    assert (
 | 
				
			||||||
        f"arn:aws:kinesis:us-east-1:{DEFAULT_ACCOUNT_ID}:stream/{stream_name}"
 | 
					        resp["StreamARN"]
 | 
				
			||||||
 | 
					        == f"arn:aws:kinesis:us-east-1:{DEFAULT_ACCOUNT_ID}:stream/{stream_name}"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -35,7 +36,7 @@ def test_enable_enhanced_monitoring_is_persisted():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
					    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
				
			||||||
    metrics = stream["EnhancedMonitoring"][0]["ShardLevelMetrics"]
 | 
					    metrics = stream["EnhancedMonitoring"][0]["ShardLevelMetrics"]
 | 
				
			||||||
    set(metrics).should.equal({"IncomingBytes", "OutgoingBytes"})
 | 
					    assert set(metrics) == {"IncomingBytes", "OutgoingBytes"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -52,22 +53,20 @@ def test_enable_enhanced_monitoring_in_steps():
 | 
				
			|||||||
        StreamName=stream_name, ShardLevelMetrics=["WriteProvisionedThroughputExceeded"]
 | 
					        StreamName=stream_name, ShardLevelMetrics=["WriteProvisionedThroughputExceeded"]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp.should.have.key("CurrentShardLevelMetrics").should.have.length_of(2)
 | 
					    assert len(resp["CurrentShardLevelMetrics"]) == 2
 | 
				
			||||||
    resp["CurrentShardLevelMetrics"].should.contain("IncomingBytes")
 | 
					    assert "IncomingBytes" in resp["CurrentShardLevelMetrics"]
 | 
				
			||||||
    resp["CurrentShardLevelMetrics"].should.contain("OutgoingBytes")
 | 
					    assert "OutgoingBytes" in resp["CurrentShardLevelMetrics"]
 | 
				
			||||||
    resp.should.have.key("DesiredShardLevelMetrics").should.have.length_of(3)
 | 
					    assert len(resp["DesiredShardLevelMetrics"]) == 3
 | 
				
			||||||
    resp["DesiredShardLevelMetrics"].should.contain("IncomingBytes")
 | 
					    assert "IncomingBytes" in resp["DesiredShardLevelMetrics"]
 | 
				
			||||||
    resp["DesiredShardLevelMetrics"].should.contain("OutgoingBytes")
 | 
					    assert "OutgoingBytes" in resp["DesiredShardLevelMetrics"]
 | 
				
			||||||
    resp["DesiredShardLevelMetrics"].should.contain(
 | 
					    assert "WriteProvisionedThroughputExceeded" in resp["DesiredShardLevelMetrics"]
 | 
				
			||||||
        "WriteProvisionedThroughputExceeded"
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
					    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
				
			||||||
    metrics = stream["EnhancedMonitoring"][0]["ShardLevelMetrics"]
 | 
					    metrics = stream["EnhancedMonitoring"][0]["ShardLevelMetrics"]
 | 
				
			||||||
    metrics.should.have.length_of(3)
 | 
					    assert len(metrics) == 3
 | 
				
			||||||
    metrics.should.contain("IncomingBytes")
 | 
					    assert "IncomingBytes" in metrics
 | 
				
			||||||
    metrics.should.contain("OutgoingBytes")
 | 
					    assert "OutgoingBytes" in metrics
 | 
				
			||||||
    metrics.should.contain("WriteProvisionedThroughputExceeded")
 | 
					    assert "WriteProvisionedThroughputExceeded" in metrics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -90,35 +89,32 @@ def test_disable_enhanced_monitoring():
 | 
				
			|||||||
        StreamName=stream_name, ShardLevelMetrics=["OutgoingBytes"]
 | 
					        StreamName=stream_name, ShardLevelMetrics=["OutgoingBytes"]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp.should.have.key("StreamName").equals(stream_name)
 | 
					    assert resp["StreamName"] == stream_name
 | 
				
			||||||
    resp.should.have.key("StreamARN").equals(
 | 
					    assert (
 | 
				
			||||||
        f"arn:aws:kinesis:us-east-1:{DEFAULT_ACCOUNT_ID}:stream/{stream_name}"
 | 
					        resp["StreamARN"]
 | 
				
			||||||
 | 
					        == f"arn:aws:kinesis:us-east-1:{DEFAULT_ACCOUNT_ID}:stream/{stream_name}"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp.should.have.key("CurrentShardLevelMetrics").should.have.length_of(3)
 | 
					    assert len(resp["CurrentShardLevelMetrics"]) == 3
 | 
				
			||||||
    resp["CurrentShardLevelMetrics"].should.contain("IncomingBytes")
 | 
					    assert "IncomingBytes" in resp["CurrentShardLevelMetrics"]
 | 
				
			||||||
    resp["CurrentShardLevelMetrics"].should.contain("OutgoingBytes")
 | 
					    assert "OutgoingBytes" in resp["CurrentShardLevelMetrics"]
 | 
				
			||||||
    resp["CurrentShardLevelMetrics"].should.contain(
 | 
					    assert "WriteProvisionedThroughputExceeded" in resp["CurrentShardLevelMetrics"]
 | 
				
			||||||
        "WriteProvisionedThroughputExceeded"
 | 
					    assert len(resp["DesiredShardLevelMetrics"]) == 2
 | 
				
			||||||
    )
 | 
					    assert "IncomingBytes" in resp["DesiredShardLevelMetrics"]
 | 
				
			||||||
    resp.should.have.key("DesiredShardLevelMetrics").should.have.length_of(2)
 | 
					    assert "WriteProvisionedThroughputExceeded" in resp["DesiredShardLevelMetrics"]
 | 
				
			||||||
    resp["DesiredShardLevelMetrics"].should.contain("IncomingBytes")
 | 
					 | 
				
			||||||
    resp["DesiredShardLevelMetrics"].should.contain(
 | 
					 | 
				
			||||||
        "WriteProvisionedThroughputExceeded"
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
					    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
				
			||||||
    metrics = stream["EnhancedMonitoring"][0]["ShardLevelMetrics"]
 | 
					    metrics = stream["EnhancedMonitoring"][0]["ShardLevelMetrics"]
 | 
				
			||||||
    metrics.should.have.length_of(2)
 | 
					    assert len(metrics) == 2
 | 
				
			||||||
    metrics.should.contain("IncomingBytes")
 | 
					    assert "IncomingBytes" in metrics
 | 
				
			||||||
    metrics.should.contain("WriteProvisionedThroughputExceeded")
 | 
					    assert "WriteProvisionedThroughputExceeded" in metrics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp = client.disable_enhanced_monitoring(
 | 
					    resp = client.disable_enhanced_monitoring(
 | 
				
			||||||
        StreamARN=stream_arn, ShardLevelMetrics=["IncomingBytes"]
 | 
					        StreamARN=stream_arn, ShardLevelMetrics=["IncomingBytes"]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp.should.have.key("CurrentShardLevelMetrics").should.have.length_of(2)
 | 
					    assert len(resp["CurrentShardLevelMetrics"]) == 2
 | 
				
			||||||
    resp.should.have.key("DesiredShardLevelMetrics").should.have.length_of(1)
 | 
					    assert len(resp["DesiredShardLevelMetrics"]) == 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -142,4 +138,4 @@ def test_disable_enhanced_monitoring_all():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
					    stream = client.describe_stream(StreamName=stream_name)["StreamDescription"]
 | 
				
			||||||
    metrics = stream["EnhancedMonitoring"][0]["ShardLevelMetrics"]
 | 
					    metrics = stream["EnhancedMonitoring"][0]["ShardLevelMetrics"]
 | 
				
			||||||
    metrics.should.equal([])
 | 
					    assert metrics == []
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ def test_list_stream_consumers():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    resp = client.list_stream_consumers(StreamARN=stream_arn)
 | 
					    resp = client.list_stream_consumers(StreamARN=stream_arn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp.should.have.key("Consumers").equals([])
 | 
					    assert resp["Consumers"] == []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -31,27 +31,29 @@ def test_register_stream_consumer():
 | 
				
			|||||||
    resp = client.register_stream_consumer(
 | 
					    resp = client.register_stream_consumer(
 | 
				
			||||||
        StreamARN=stream_arn, ConsumerName="newconsumer"
 | 
					        StreamARN=stream_arn, ConsumerName="newconsumer"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    resp.should.have.key("Consumer")
 | 
					    assert "Consumer" in resp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    consumer = resp["Consumer"]
 | 
					    consumer = resp["Consumer"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    consumer.should.have.key("ConsumerName").equals("newconsumer")
 | 
					    assert consumer["ConsumerName"] == "newconsumer"
 | 
				
			||||||
    consumer.should.have.key("ConsumerARN").equals(
 | 
					    assert (
 | 
				
			||||||
        f"arn:aws:kinesis:eu-west-1:{ACCOUNT_ID}:stream/my-stream/consumer/newconsumer"
 | 
					        consumer["ConsumerARN"]
 | 
				
			||||||
 | 
					        == f"arn:aws:kinesis:eu-west-1:{ACCOUNT_ID}:stream/my-stream/consumer/newconsumer"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    consumer.should.have.key("ConsumerStatus").equals("ACTIVE")
 | 
					    assert consumer["ConsumerStatus"] == "ACTIVE"
 | 
				
			||||||
    consumer.should.have.key("ConsumerCreationTimestamp")
 | 
					    assert "ConsumerCreationTimestamp" in consumer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp = client.list_stream_consumers(StreamARN=stream_arn)
 | 
					    resp = client.list_stream_consumers(StreamARN=stream_arn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp.should.have.key("Consumers").length_of(1)
 | 
					    assert len(resp["Consumers"]) == 1
 | 
				
			||||||
    consumer = resp["Consumers"][0]
 | 
					    consumer = resp["Consumers"][0]
 | 
				
			||||||
    consumer.should.have.key("ConsumerName").equals("newconsumer")
 | 
					    assert consumer["ConsumerName"] == "newconsumer"
 | 
				
			||||||
    consumer.should.have.key("ConsumerARN").equals(
 | 
					    assert (
 | 
				
			||||||
        f"arn:aws:kinesis:eu-west-1:{ACCOUNT_ID}:stream/my-stream/consumer/newconsumer"
 | 
					        consumer["ConsumerARN"]
 | 
				
			||||||
 | 
					        == f"arn:aws:kinesis:eu-west-1:{ACCOUNT_ID}:stream/my-stream/consumer/newconsumer"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    consumer.should.have.key("ConsumerStatus").equals("ACTIVE")
 | 
					    assert consumer["ConsumerStatus"] == "ACTIVE"
 | 
				
			||||||
    consumer.should.have.key("ConsumerCreationTimestamp")
 | 
					    assert "ConsumerCreationTimestamp" in consumer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -63,14 +65,14 @@ def test_describe_stream_consumer_by_name():
 | 
				
			|||||||
    resp = client.describe_stream_consumer(
 | 
					    resp = client.describe_stream_consumer(
 | 
				
			||||||
        StreamARN=stream_arn, ConsumerName="newconsumer"
 | 
					        StreamARN=stream_arn, ConsumerName="newconsumer"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    resp.should.have.key("ConsumerDescription")
 | 
					    assert "ConsumerDescription" in resp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    consumer = resp["ConsumerDescription"]
 | 
					    consumer = resp["ConsumerDescription"]
 | 
				
			||||||
    consumer.should.have.key("ConsumerName").equals("newconsumer")
 | 
					    assert consumer["ConsumerName"] == "newconsumer"
 | 
				
			||||||
    consumer.should.have.key("ConsumerARN")
 | 
					    assert "ConsumerARN" in consumer
 | 
				
			||||||
    consumer.should.have.key("ConsumerStatus").equals("ACTIVE")
 | 
					    assert consumer["ConsumerStatus"] == "ACTIVE"
 | 
				
			||||||
    consumer.should.have.key("ConsumerCreationTimestamp")
 | 
					    assert "ConsumerCreationTimestamp" in consumer
 | 
				
			||||||
    consumer.should.have.key("StreamARN").equals(stream_arn)
 | 
					    assert consumer["StreamARN"] == stream_arn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -83,14 +85,14 @@ def test_describe_stream_consumer_by_arn():
 | 
				
			|||||||
    consumer_arn = resp["Consumer"]["ConsumerARN"]
 | 
					    consumer_arn = resp["Consumer"]["ConsumerARN"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp = client.describe_stream_consumer(ConsumerARN=consumer_arn)
 | 
					    resp = client.describe_stream_consumer(ConsumerARN=consumer_arn)
 | 
				
			||||||
    resp.should.have.key("ConsumerDescription")
 | 
					    assert "ConsumerDescription" in resp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    consumer = resp["ConsumerDescription"]
 | 
					    consumer = resp["ConsumerDescription"]
 | 
				
			||||||
    consumer.should.have.key("ConsumerName").equals("newconsumer")
 | 
					    assert consumer["ConsumerName"] == "newconsumer"
 | 
				
			||||||
    consumer.should.have.key("ConsumerARN")
 | 
					    assert "ConsumerARN" in consumer
 | 
				
			||||||
    consumer.should.have.key("ConsumerStatus").equals("ACTIVE")
 | 
					    assert consumer["ConsumerStatus"] == "ACTIVE"
 | 
				
			||||||
    consumer.should.have.key("ConsumerCreationTimestamp")
 | 
					    assert "ConsumerCreationTimestamp" in consumer
 | 
				
			||||||
    consumer.should.have.key("StreamARN").equals(stream_arn)
 | 
					    assert consumer["StreamARN"] == stream_arn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -102,10 +104,8 @@ def test_describe_stream_consumer_unknown():
 | 
				
			|||||||
    with pytest.raises(ClientError) as exc:
 | 
					    with pytest.raises(ClientError) as exc:
 | 
				
			||||||
        client.describe_stream_consumer(ConsumerARN=unknown_arn)
 | 
					        client.describe_stream_consumer(ConsumerARN=unknown_arn)
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ResourceNotFoundException")
 | 
					    assert err["Code"] == "ResourceNotFoundException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert err["Message"] == f"Consumer {unknown_arn}, account {ACCOUNT_ID} not found."
 | 
				
			||||||
        f"Consumer {unknown_arn}, account {ACCOUNT_ID} not found."
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -116,15 +116,11 @@ def test_deregister_stream_consumer_by_name():
 | 
				
			|||||||
    client.register_stream_consumer(StreamARN=stream_arn, ConsumerName="consumer1")
 | 
					    client.register_stream_consumer(StreamARN=stream_arn, ConsumerName="consumer1")
 | 
				
			||||||
    client.register_stream_consumer(StreamARN=stream_arn, ConsumerName="consumer2")
 | 
					    client.register_stream_consumer(StreamARN=stream_arn, ConsumerName="consumer2")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.list_stream_consumers(StreamARN=stream_arn)[
 | 
					    assert len(client.list_stream_consumers(StreamARN=stream_arn)["Consumers"]) == 2
 | 
				
			||||||
        "Consumers"
 | 
					 | 
				
			||||||
    ].should.have.length_of(2)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.deregister_stream_consumer(StreamARN=stream_arn, ConsumerName="consumer1")
 | 
					    client.deregister_stream_consumer(StreamARN=stream_arn, ConsumerName="consumer1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.list_stream_consumers(StreamARN=stream_arn)[
 | 
					    assert len(client.list_stream_consumers(StreamARN=stream_arn)["Consumers"]) == 1
 | 
				
			||||||
        "Consumers"
 | 
					 | 
				
			||||||
    ].should.have.length_of(1)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -138,12 +134,8 @@ def test_deregister_stream_consumer_by_arn():
 | 
				
			|||||||
    consumer1_arn = resp["Consumer"]["ConsumerARN"]
 | 
					    consumer1_arn = resp["Consumer"]["ConsumerARN"]
 | 
				
			||||||
    client.register_stream_consumer(StreamARN=stream_arn, ConsumerName="consumer2")
 | 
					    client.register_stream_consumer(StreamARN=stream_arn, ConsumerName="consumer2")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.list_stream_consumers(StreamARN=stream_arn)[
 | 
					    assert len(client.list_stream_consumers(StreamARN=stream_arn)["Consumers"]) == 2
 | 
				
			||||||
        "Consumers"
 | 
					 | 
				
			||||||
    ].should.have.length_of(2)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.deregister_stream_consumer(ConsumerARN=consumer1_arn)
 | 
					    client.deregister_stream_consumer(ConsumerARN=consumer1_arn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client.list_stream_consumers(StreamARN=stream_arn)[
 | 
					    assert len(client.list_stream_consumers(StreamARN=stream_arn)["Consumers"]) == 1
 | 
				
			||||||
        "Consumers"
 | 
					 | 
				
			||||||
    ].should.have.length_of(1)
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
import boto3
 | 
					import boto3
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
import sure  # noqa # pylint: disable=unused-import
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from botocore.exceptions import ClientError
 | 
					from botocore.exceptions import ClientError
 | 
				
			||||||
from moto import mock_kinesis
 | 
					from moto import mock_kinesis
 | 
				
			||||||
@ -19,9 +18,10 @@ def test_record_data_exceeds_1mb():
 | 
				
			|||||||
            StreamName="my_stream",
 | 
					            StreamName="my_stream",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ValidationException")
 | 
					    assert err["Code"] == "ValidationException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "1 validation error detected: Value at 'records.1.member.data' failed to satisfy constraint: Member must have length less than or equal to 1048576"
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "1 validation error detected: Value at 'records.1.member.data' failed to satisfy constraint: Member must have length less than or equal to 1048576"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -39,9 +39,10 @@ def test_record_data_and_partition_key_exceeds_1mb():
 | 
				
			|||||||
            StreamName="my_stream",
 | 
					            StreamName="my_stream",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ValidationException")
 | 
					    assert err["Code"] == "ValidationException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "1 validation error detected: Value at 'records.1.member.data' failed to satisfy constraint: Member must have length less than or equal to 1048576"
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "1 validation error detected: Value at 'records.1.member.data' failed to satisfy constraint: Member must have length less than or equal to 1048576"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -84,8 +85,8 @@ def test_total_record_data_exceeds_5mb():
 | 
				
			|||||||
            StreamName="my_stream",
 | 
					            StreamName="my_stream",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("InvalidArgumentException")
 | 
					    assert err["Code"] == "InvalidArgumentException"
 | 
				
			||||||
    err["Message"].should.equal("Records size exceeds 5 MB limit")
 | 
					    assert err["Message"] == "Records size exceeds 5 MB limit"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@mock_kinesis
 | 
					@mock_kinesis
 | 
				
			||||||
@ -112,7 +113,8 @@ def test_too_many_records():
 | 
				
			|||||||
            StreamName="my_stream",
 | 
					            StreamName="my_stream",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    err = exc.value.response["Error"]
 | 
					    err = exc.value.response["Error"]
 | 
				
			||||||
    err["Code"].should.equal("ValidationException")
 | 
					    assert err["Code"] == "ValidationException"
 | 
				
			||||||
    err["Message"].should.equal(
 | 
					    assert (
 | 
				
			||||||
        "1 validation error detected: Value at 'records' failed to satisfy constraint: Member must have length less than or equal to 500"
 | 
					        err["Message"]
 | 
				
			||||||
 | 
					        == "1 validation error detected: Value at 'records' failed to satisfy constraint: Member must have length less than or equal to 500"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,4 @@
 | 
				
			|||||||
import json
 | 
					import json
 | 
				
			||||||
import sure  # noqa # pylint: disable=unused-import
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import moto.server as server
 | 
					import moto.server as server
 | 
				
			||||||
from moto import mock_kinesis
 | 
					from moto import mock_kinesis
 | 
				
			||||||
@ -13,4 +12,4 @@ def test_list_streams():
 | 
				
			|||||||
    res = test_client.get("/?Action=ListStreams")
 | 
					    res = test_client.get("/?Action=ListStreams")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    json_data = json.loads(res.data.decode("utf-8"))
 | 
					    json_data = json.loads(res.data.decode("utf-8"))
 | 
				
			||||||
    json_data.should.equal({"HasMoreStreams": False, "StreamNames": []})
 | 
					    assert json_data == {"HasMoreStreams": False, "StreamNames": []}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user