用Moto模拟多个AWS服务

时间:2019-11-27 21:20:51

标签: pytest boto3 moto

我正在尝试模拟计算环境的创建,这需要其他一些资源,即IAM实例配置文件和服务角色。但是,当我创建这些IAM资源,然后尝试在计算环境创建中使用它们时,事情失败了:

Question 1

代码如下:

    public static async Task RunWithoutBlocking(IEnumerable<Func<Task>> actions)
    {
        var currentSyncContext = SynchronizationContext.Current;
        try
        {
            SynchronizationContext.SetSynchronizationContext(null);
            foreach (var action in actions)
            {
                await action();
            }
        }
        finally
        {
            SynchronizationContext.SetSynchronizationContext(currentSyncContext);
        }
    }`

在测试中,我可以看到IAM对象的打印,因此我知道它们是在创建的。这些只是不跨moto模拟共享吗?

<Message>Role arn:aws:iam::123456789012:instance-profile/InstanceProfile not found</Message>

我知道,如果我们可以通过实例配置文件,这可能不是一个完整的工作示例,但这就是现在的问题所在。

任何见解都值得赞赏。非常感谢!

1 个答案:

答案 0 :(得分:0)

我能够克服这个困难,希望这对其他人有帮助。简要地说,我创建了固定装置,并在需要它们的地方传递了服务。


@pytest.fixture()
def vpc():
    mock = mock_ec2()
    mock.start()
    ec2 = boto3.resource("ec2")
    vpc = ec2.create_vpc(CidrBlock="172.16.0.0/16")
    vpc.wait_until_available()
    ec2.create_subnet(CidrBlock="172.16.0.1/24", VpcId=vpc.id)
    ec2.create_security_group(
        Description="Test security group", GroupName="sg1", VpcId=vpc.id
    )
    yield vpc
    mock.stop()


@pytest.fixture()
def iam_resource():
    mock = mock_iam()
    mock.start()
    yield boto3.resource("iam")
    mock.stop()


@pytest.fixture()
def batch_client():
    mock = mock_batch()
    mock.start()
    yield boto3.client("batch")
    mock.stop()


@pytest.fixture()
def batch_roles(iam_resource) -> Tuple[Any, Any]:
    iam = iam_resource

    service_role = iam.create_role(
        RoleName="BatchServiceRole",
        AssumeRolePolicyDocument=json.dumps(
            {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {"Service": "batch.amazonaws.com"},
                        "Action": "sts:AssumeRole",
                    }
                ],
            }
        ),
    )
    instance_role = iam.create_role(
        RoleName="InstanceRole",
        AssumeRolePolicyDocument=json.dumps(
            {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {"Service": "ec2.amazonaws.com"},
                        "Action": "sts:AssumeRole",
                    }
                ],
            }
        ),
    )
    return service_role, instance_role

@pytest.fixture()
def batch_compute_environments(
    lims_objs, batch_client, batch_roles, vpc
):
    ...

然后,我可以使用与上述相同的方式创建的这些固定装置和其他固定装置来模拟测试提交作业。

def test_submit_batch(
    lims_objs,
    batch_client,
    batch_compute_environments,
    batch_job_definitions,
    batch_queue,
    capsys,
):
    client = batch_client
    for (env, assay), lims in lims_objs.items():
        name = f"pytest_batch_job_{env.name}_{assay.name}"
        res = client.submit_job(
            jobName="pytest_" + name,
            jobQueue=lims.get_aws_name("job_queue"),
            jobDefinition=lims.get_aws_name("job_definition"),
            parameters={
                "assay": "...",
                "runid": name,
                "reqid": "pytest",
                "env": env.name,
            },
        )

        assert res["ResponseMetadata"]["HTTPStatusCode"] == requests.codes.ok
        ...