Git Product home page Git Product logo

Comments (3)

bblommers avatar bblommers commented on June 20, 2024 1

No problem @andymadge! Glad I could help. I'll close this, but let us know if you have any other questions.

from moto.

bblommers avatar bblommers commented on June 20, 2024

Hi @andymadge! There are two things at play here:

  • The mock_aws-decorator overwrites the config everytime it starts.
  • Functions created in a mock without docker are stored separately from functions in a mock where docker is enabled

Your example effectively does the following:

# The fixture is executed first by pytest, starting a mock with docker enabled (lambda: {use_docker: True} is the default)
mock_aws(config=None)

# Create function in the lambda with Docker enabled
docker_lambda.create_function()
docker_lambda.list_function()

# Now the test-decorator starts
# Start a Mock without docker
@mock_aws(config={"lambda": {"use_docker": False},})

# We now list the functions inside the docker-less lambda
dockerless_lambda.list_functions == []

The easiest way to fix this would be to only have a single decorator inside your test case, so it's always obvious which configuration is active at any given point. One way to do this is to have a single fixture:


@pytest.fixture(scope='function')
def aws_credentials():
    ...


@pytest.fixture
def dockerless_fake_aws(aws_credentials):
    with mock_aws(config={"lambda": {"use_docker": False}}):
        yield

@pytest.fixture
def dummy_lambda(dockerless_fake_aws):
    client = boto3.client("lambda", LAMBDA_REGION)
    zip_content = get_test_zip_file1()
    role = get_role_name()
    client.create_function(
        FunctionName="LambdaFunctionDummyName",
        Runtime="3.12",
        Role=role,
        Handler="lambda_function.lambda_handler",
        Code={"ZipFile": zip_content},
        Description="test lambda function",
        Timeout=3,
        MemorySize=128,
        Publish=True,
    )
    # print(client.list_functions()['Functions'], "\n")
    print(boto3.client('lambda', LAMBDA_REGION).list_functions()['Functions'], "\n")
    yield client



def test_lambda(dummy_lambda):
    # print(dummy_lambda.list_functions()['Functions'], "\n")
    print(boto3.client('lambda', LAMBDA_REGION).list_functions()['Functions'], "\n")
    # print(boto3.client('sts').get_caller_identity())
    assert True



### Utilities ###

def get_test_zip_file1():
    ...


def get_role_name():
    '''Create a role for the lambda function to assume and return the ARN. If the role already exists, return the ARN.'''
    iam = boto3.client("iam", region_name=LAMBDA_REGION)
    while True:
        try:
            return iam.get_role(RoleName="my-role")["Role"]["Arn"]
        except ClientError:
            try:
                return iam.create_role(
                    RoleName="my-role",
                    AssumeRolePolicyDocument="some policy",
                    Path="/my-path/",
                )["Role"]["Arn"]
            except ClientError:
                pass

Note that I've also removed the decorator from the get_role_name - as long as this function is always executed within the context of another function with mock_aws active, there's no reason to apply it again.

I also added the LAMBDA_REGION explicitly to every boto3.client-initialization, just to ensure that they are not executed within my system-default region.

from moto.

andymadge avatar andymadge commented on June 20, 2024

Thanks, that makes sense. I had wondered if it needed configuring earlier, but the only way I could see to configure it differently was by adding the decorator to fixtures, but that didn't seem to do anything.

I can see now that I needed to add the config to the original call to mock_aws() rather than as a decorator.

So just to check my understanding...

  • If you want to configure mock_aws(), then you need to do it when it is instantiated (obvious really, but I just wasn't thinking of it in those terms)
  • Therefore if you are instantiating it manually, with mock = mock_aws() or a context manager, then you include the config in the call to mock_aws()
  • If you use the decorator it will implicitly create the mock, so you include the config in the decorator

These creation options are covered in https://docs.getmoto.org/en/latest/docs/getting_started.html#moto-usage but I had failed to grasp the fact that this is also the place to configure it.

That all seems completely obvious now that I know. Of course you need to configure the object instance when you create it, but my understanding of Moto was lacking and I wasn't piecing together the various ways of instantiating Moto to understand each of them.

Thanks for taking the time to explain.

from moto.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.