예제 #1
0
def test_get_service_calls(lob: lobotomy.Lobotomy):
    """Should correctly retrieve service calls made."""
    lob.data = {
        "clients": {
            "sts": {
                "get_caller_identity": {
                    "Account": "123"
                }
            }
        }
    }
    session = lob()
    client = session.client("sts")

    assert client.get_caller_identity()["Account"] == "123"
    assert client.get_caller_identity(
    )["Account"] == "123", "Expected to work twice."

    assert len(lob.service_calls) == 2
    assert len(lob.get_service_calls("sts", "get_caller_identity")) == 2
    assert lob.get_service_call("sts", "get_caller_identity", 0)
    assert lob.get_service_call("sts", "get_caller_identity", 1)

    with pytest.raises(IndexError):
        lob.get_service_call("sts", "get_caller_identity", 2)
예제 #2
0
def test_missing_request_arguments(lobotomized: lobotomy.Lobotomy):
    """Should fail due to missing "Bucket" request argument."""
    lobotomized.add_call("s3", "list_objects", {})
    session = boto3.Session()
    client = session.client("s3")
    with pytest.raises(lobotomy.RequestValidationError):
        client.list_objects()
예제 #3
0
def test_unknown_request_arguments(lobotomized: lobotomy.Lobotomy):
    """Should fail due to presence of unknown "Foo" argument."""
    lobotomized.add_call("s3", "list_objects", {})
    session = boto3.Session()
    client = session.client("s3")
    with pytest.raises(lobotomy.RequestValidationError):
        client.list_objects(Bucket="foo", Foo="bar")
예제 #4
0
def test_bad_casting(lobotomized: lobotomy.Lobotomy):
    """Should fail to cast dictionary as string."""
    lobotomized.add_call("s3", "list_objects",
                         {"Contents": ["should-be-dict"]})
    session = boto3.Session()
    client = session.client("s3")
    with pytest.raises(lobotomy.DataTypeError):
        client.list_objects(Bucket="foo")
예제 #5
0
def test_dynamodb_get_item(lobotomized: lobotomy.Lobotomy):
    """Should handle dynamodb.get_item without recursion errors."""
    lobotomized.data = {"clients": {"dynamodb": {"get_item": {}}}}
    session = lobotomized()
    client = session.client("dynamodb")
    client.get_item(TableName="foo", Key={"pk": {"S": "spam"}, "sk": {"S": "ham"}})

    call = lobotomized.get_service_calls("dynamodb", "get_item")[0]
    assert call.request["TableName"] == "foo"
def test_timestamp_formats(lobotomized: lobotomy.Lobotomy, value: typing.Any):
    """Should cast timestamp values correctly."""
    lobotomized.add_call("iam", "get_role", response={"Role": {"CreateDate": value}})
    response = boto3.Session().client("iam").get_role(RoleName="foo")
    observed: datetime.datetime = response["Role"]["CreateDate"]
    assert isinstance(observed, datetime.datetime)
    assert observed.date() == datetime.date(2020, 1, 1)
    assert observed.hour in (0, 12)
    assert observed.minute in (0, 23)
    assert observed.second in (0, 34)
예제 #7
0
def test_client_error_convenience(lobotomized: lobotomy.Lobotomy):
    """Should create an error response."""
    lobotomized.add_error_call("s3", "list_objects", "NoSuchBucket",
                               "Hello...")
    client = lobotomized().client("s3")

    session = boto3.Session()
    client = session.client("s3")
    with pytest.raises(client.exceptions.NoSuchBucket):
        client.list_objects(Bucket="foo")
def test_s3_download_file(lobotomized: lobotomy.Lobotomy):
    """Should handle s3.download_file correctly despite it being an augmentation."""
    lobotomized.data = {"clients": {"s3": {"download_file": {}}}}
    session = lobotomized()
    client = session.client("s3")
    client.download_file(Filename="foo", Bucket="bar", Key="baz")

    call = lobotomized.get_service_calls("s3", "download_file")[0]
    assert call.request["Filename"] == "foo"
    assert call.request["Bucket"] == "bar"
    assert call.request["Key"] == "baz"
예제 #9
0
def test_s3_select(lobotomized: lobotomy.Lobotomy):
    """Should correctly return S3 Select results."""
    lobotomized.add_call(
        "s3",
        "select_object_content",
        {
            "Payload": [
                {
                    "Records": {
                        "Payload": "a"
                    }
                },
                {
                    "Records": {
                        "Payload": "b"
                    }
                },
                {
                    "Records": {
                        "Payload": "c"
                    }
                },
            ]
        },
    )

    response = (lobotomized().client("s3").select_object_content(
        Bucket="foo",
        Key="bar/baz.file",
        InputSerialization={"Parquet": {}},
        Expression="SELECT * FROM S3Object LIMIT 100",
        ExpressionType="SQL",
        OutputSerialization={"JSON": {
            "RecordDelimiter": "\n"
        }},
    ))
    observed = list(response["Payload"])
    assert observed == [
        {
            "Records": {
                "Payload": b"a"
            }
        },
        {
            "Records": {
                "Payload": b"b"
            }
        },
        {
            "Records": {
                "Payload": b"c"
            }
        },
    ]
예제 #10
0
def test_sqs_delete_message(lobotomized: lobotomy.Lobotomy):
    """
    Should handle sqs.delete_message without error despite edge case
    configuration in botocore service method definitions where the return
    structure has no members.
    """
    lobotomized.add_call("sqs", "delete_message")
    lobotomized().client("sqs").delete_message(
        QueueUrl="https://sqs.us-west-2.amazonaws.com/123/my-queue",
        ReceiptHandle="fake-receipt-handle",
    )
    assert lobotomized.get_service_call("sqs", "delete_message") is not None
예제 #11
0
def test_pagination(lobotomized: lobotomy.Lobotomy):
    """Should paginate correctly by using only the first response."""
    lobotomized.add_call("s3", "list_objects_v2", {"Contents": [{"Key": "a"}]})
    lobotomized.add_call("s3", "list_objects_v2", {"Contents": [{"Key": "b"}]})

    session = lobotomized()
    client = session.client("s3")

    paginator = client.get_paginator("list_objects_v2")
    pages = []
    for page in paginator.paginate(Bucket="my-bucket"):
        pages.append(page)

    assert pages == [{"Contents": [{"Key": "a"}]}]
예제 #12
0
def test_eks_describe_cluster(lobotomized: lobotomy.Lobotomy):
    """Should return result without error."""
    lobotomized.add_call(
        "eks",
        "describe_cluster",
        response={
            "name": "cluster-name",
            "arn": "arn:aws:eks:us-west-2:123456:cluster/cluster-name",
            "certificateAuthority": {
                "data": "fakecertificatedata="
            },
        },
    )
    response = lobotomized().client("eks").describe_cluster("cluster-name")
    assert response[
        "arn"] == "arn:aws:eks:us-west-2:123456:cluster/cluster-name"
예제 #13
0
def test_creation_empty_patched(lob: lobotomy.Lobotomy):
    """Should patch an empty lobotomy and then work after setting data manually."""
    lob.data = {
        "clients": {
            "sts": {
                "get_caller_identity": {
                    "Account": "123"
                }
            }
        }
    }
    session = lob()
    client = session.client("sts")
    assert client.get_caller_identity()["Account"] == "123"
    assert len(lob.service_calls) == 1
    assert len(lob.get_service_calls("sts", "get_caller_identity")) == 1
예제 #14
0
def test_client_errors(lobotomized: lobotomy.Lobotomy):
    """Should raise the specified error."""
    lobotomized.add_call(
        service_name="s3",
        method_name="list_objects",
        response={"Error": {
            "Code": "NoSuchBucket",
            "Message": "Hello..."
        }},
    )
    session = boto3.Session()
    client = session.client("s3")
    with pytest.raises(client.exceptions.NoSuchBucket):
        client.list_objects(Bucket="foo")

    with pytest.raises(lobotomy.ClientError) as exception_info:
        client.list_objects(Bucket="foo")

    assert exception_info.value.response["Error"]["Code"] == "NoSuchBucket"
예제 #15
0
def test_session_properties(lob: lobotomy.Lobotomy):
    """Should return the expected values for session properties."""
    session_data = {
        "profile_name": "foo-bar",
        "region_name": "us-north-1",
        "available_profiles": ["foo-bar", "baz"],
    }
    lob.data = {"session": session_data}
    session = lob()
    assert session.profile_name == "foo-bar"
    assert session.region_name == "us-north-1"
    assert session.available_profiles == ["foo-bar", "baz"]
예제 #16
0
def _process_action(
    lobotomized: lobotomy.Lobotomy,
    action: typing.Dict[str, typing.Any],
) -> None:
    """Mutates the lobotomized data according the specified action."""
    kind = action.get("kind")
    data = lobotomized.data
    clients = data.get("clients", {})

    if kind == "remove_service_calls":
        service = action["service"]
        method = action["method"]
        del clients[service][method]
    elif kind == "remove_service":
        service = action["service"]
        del clients[service]
    elif kind == "add_service_call":
        lobotomized.add_call(
            service_name=action["service"],
            method_name=action["method"],
            response=action.get("response"),
        )
예제 #17
0
def test_credentials(lob: lobotomy.Lobotomy):
    """Should return the expected values for session credentials."""
    credentials = {
        "method": "foo",
        "access_key": "A123",
        "secret_key": "123abc",
        "token": "foobar",
    }
    lob.data = {"session": {"credentials": credentials}}
    session = lob()
    observed = session.get_credentials()
    assert observed.method == "foo"
    assert observed.access_key == "A123"
    assert observed.secret_key == "123abc"
    assert observed.token == "foobar"

    frozen = observed.get_frozen_credentials()
    assert frozen.access_key == "A123"
    assert frozen.secret_key == "123abc"
    assert frozen.token == "foobar"
예제 #18
0
def test_override_manual(lob: lobotomy.Lobotomy):
    """Should return the override dictionary for the STS client."""
    session = lob.add_client_override("sts", {"foo": "bar"})()
    assert session.client("sts") == {"foo": "bar"}
예제 #19
0
def test_override_removed(lob: lobotomy.Lobotomy):
    """Should not return the override dictionary for the STS client if removed."""
    session = lob.remove_client_override("sts")()
    assert session.client("sts") != {"foo": "bar"}
    assert isinstance(session.client("sts"), lobotomy.Client)
예제 #20
0
def test_creation_empty_added(lob: lobotomy.Lobotomy):
    """Should patch an empty lobotomy and then work after setting data manually."""
    lob.add_call("sts", "get_caller_identity", {"Account": "123"})
    session = lob()
    client = session.client("sts")
    assert client.get_caller_identity()["Account"] == "123"
예제 #21
0
def test_lambda_invoke(lobotomized: lobotomy.Lobotomy):
    """Should return a StreamingBody for the payload."""
    lobotomized.add_call("lambda", "invoke")
    response = lobotomized().client("lambda").invoke(FunctionName="foo")
    assert b"..." == response["Payload"].read()