zapier/moto

Name: moto

Owner: Zapier

Description: Moto is a library that allows your python tests to easily mock out the boto library

Forked from: spulec/moto

Created: 2018-01-18 01:10:29.0

Updated: 2018-01-18 01:10:32.0

Pushed: 2018-01-18 01:12:11.0

Homepage: null

Size: 6816

Language: Python

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Moto - Mock AWS Services

Join the chat at https://gitter.im/awsmoto/Lobby

Build Status Coverage Status Docs

In a nutshell

Moto is a library that allows your tests to easily mock out AWS Services.

Imagine you have the following python code that you want to test:

rt boto3

s MyModel(object):
def __init__(self, name, value):
    self.name = name
    self.value = value

def save(self):
    s3 = boto3.client('s3', region_name='us-east-1')
    s3.put_object(Bucket='mybucket', Key=self.name, Body=self.value)

Take a minute to think how you would have tested that in the past.

Now see how you could test it with Moto:

rt boto3
 moto import mock_s3
 mymodule import MyModel


k_s3
test_my_model_save():
conn = boto3.resource('s3', region_name='us-east-1')
# We need to create the bucket since this is all in Moto's 'virtual' AWS account
conn.create_bucket(Bucket='mybucket')

model_instance = MyModel('steve', 'is awesome')
model_instance.save()

body = conn.Object('mybucket', 'steve').get()['Body'].read().decode("utf-8")

assert body == b'is awesome'

With the decorator wrapping the test, all the calls to s3 are automatically mocked out. The mock keeps the state of the buckets and keys.

It gets even better! Moto isn't just for Python code and it isn't just for S3. Look at the standalone server mode for more information about running Moto with other languages. Here's the status of the other AWS services implemented:

---------------------------------------------------------------------------|
rvice Name          | Decorator        | Development Status                |
---------------------------------------------------------------------------|
M                   | @mock_acm        | all endpoints done                |
---------------------------------------------------------------------------|
I Gateway           | @mock_apigateway | core endpoints done               |
---------------------------------------------------------------------------|
toscaling           | @mock_autoscaling| core endpoints done               |
---------------------------------------------------------------------------|
oudformation        | @mock_cloudformation| core endpoints done            |
---------------------------------------------------------------------------|
oudwatch            | @mock_cloudwatch | basic endpoints done              |
---------------------------------------------------------------------------|
oudwatchEvents      | @mock_events     | all endpoints done                |
---------------------------------------------------------------------------|
ta Pipeline         | @mock_datapipeline| basic endpoints done             |
---------------------------------------------------------------------------|
namoDB              | @mock_dynamodb   | core endpoints done               |
namoDB2             | @mock_dynamodb2  | all endpoints + partial indexes   |
---------------------------------------------------------------------------|
2                   | @mock_ec2        | core endpoints done               |
  - AMI             |                  | core endpoints done               |
  - EBS             |                  | core endpoints done               |
  - Instances       |                  | all  endpoints done               |
  - Security Groups |                  | core endpoints done               |
  - Tags            |                  | all  endpoints done               |
---------------------------------------------------------------------------|
R                   | @mock_ecr        | basic endpoints done              |
---------------------------------------------------------------------------|
S                   | @mock_ecs        | basic endpoints done              |
---------------------------------------------------------------------------|
B                   | @mock_elb        | core endpoints done               |
---------------------------------------------------------------------------|
Bv2                 | @mock_elbv2      | all endpoints done                |
---------------------------------------------------------------------------|
R                   | @mock_emr        | core endpoints done               |
---------------------------------------------------------------------------|
acier               | @mock_glacier    | core endpoints done               |
---------------------------------------------------------------------------|
M                   | @mock_iam        | core endpoints done               |
---------------------------------------------------------------------------|
T                   | @mock_iot        | core endpoints done               |
                    | @mock_iotdata    | core endpoints done               |
---------------------------------------------------------------------------|
mbda                | @mock_lambda     | basic endpoints done, requires    |
                    |                  | docker                            |
---------------------------------------------------------------------------|
gs                  | @mock_logs       | basic endpoints done              |
---------------------------------------------------------------------------|
nesis               | @mock_kinesis    | core endpoints done               |
---------------------------------------------------------------------------|
S                   | @mock_kms        | basic endpoints done              |
---------------------------------------------------------------------------|
lly                 | @mock_polly      | all endpoints done                |
---------------------------------------------------------------------------|
S                   | @mock_rds        | core endpoints done               |
---------------------------------------------------------------------------|
S2                  | @mock_rds2       | core endpoints done               |
---------------------------------------------------------------------------|
dshift              | @mock_redshift   | core endpoints done               |
---------------------------------------------------------------------------|
ute53               | @mock_route53    | core endpoints done               |
---------------------------------------------------------------------------|
                    | @mock_s3         | core endpoints done               |
---------------------------------------------------------------------------|
S                   | @mock_ses        | all endpoints done                |
---------------------------------------------------------------------------|
S                   | @mock_sns        | all endpoints done                |
---------------------------------------------------------------------------|
S                   | @mock_sqs        | core endpoints done               |
---------------------------------------------------------------------------|
M                   | @mock_ssm        | core endpoints done               |
---------------------------------------------------------------------------|
S                   | @mock_sts        | core endpoints done               |
---------------------------------------------------------------------------|
F                   | @mock_swf        | basic endpoints done              |
---------------------------------------------------------------------------|
Ray                 | @mock_xray       | all endpoints done                |
---------------------------------------------------------------------------|
Another Example

Imagine you have a function that you use to launch new ec2 instances:

rt boto3


add_servers(ami_id, count):
client = boto3.client('ec2', region_name='us-west-1')
client.run_instances(ImageId=ami_id, MinCount=count, MaxCount=count)

To test it:

 . import add_servers
 moto import mock_ec2

k_ec2
test_add_servers():
add_servers('ami-1234abcd', 2)

client = boto3.client('ec2', region_name='us-west-1')
instances = client.describe_instances()['Reservations'][0]['Instances']
assert len(instances) == 2
instance1 = instances[0]
assert instance1['ImageId'] == 'ami-1234abcd'
Using moto 1.0.X with boto2

moto 1.0.X mock docorators are defined for boto3 and do not work with boto2. Use the @mock_AWSSVC_deprecated to work with boto2.

Using moto with boto2

 moto import mock_ec2_deprecated
rt boto

k_ec2_deprecated
test_something_with_ec2():
ec2_conn = boto.ec2.connect_to_region('us-east-1')
ec2_conn.get_only_instances(instance_ids='i-123456')

When using both boto2 and boto3, one can do this to avoid confusion:

 moto import mock_ec2_deprecated as mock_ec2_b2
 moto import mock_ec2
Usage

All of the services can be used as a decorator, context manager, or in a raw form.

Decorator
k_s3
test_my_model_save():
# Create Bucket so that test can run
conn = boto3.resource('s3', region_name='us-east-1')
conn.create_bucket(Bucket='mybucket')
model_instance = MyModel('steve', 'is awesome')
model_instance.save()
body = conn.Object('mybucket', 'steve').get()['Body'].read().decode()

assert body == 'is awesome'
Context Manager
test_my_model_save():
with mock_s3():
    conn = boto3.resource('s3', region_name='us-east-1')
    conn.create_bucket(Bucket='mybucket')
    model_instance = MyModel('steve', 'is awesome')
    model_instance.save()
    body = conn.Object('mybucket', 'steve').get()['Body'].read().decode()

    assert body == 'is awesome'
Raw use
test_my_model_save():
mock = mock_s3()
mock.start()

conn = boto3.resource('s3', region_name='us-east-1')
conn.create_bucket(Bucket='mybucket')

model_instance = MyModel('steve', 'is awesome')
model_instance.save()

assert conn.Object('mybucket', 'steve').get()['Body'].read().decode() == 'is awesome'

mock.stop()
Stand-alone Server Mode

Moto also has a stand-alone server mode. This allows you to utilize the backend structure of Moto even if you don't use Python.

It uses flask, which isn't a default dependency. You can install the server 'extra' package with:

install moto[server]

You can then start it running a service:

to_server ec2
unning on http://127.0.0.1:5000/

You can also pass the port:

to_server ec2 -p3000
unning on http://127.0.0.1:3000/

If you want to be able to use the server externally you can pass an IP address to bind to as a hostname or allow any of your external interfaces with 0.0.0.0:

to_server ec2 -H 0.0.0.0
unning on http://0.0.0.0:5000/

Please be aware this might allow other network users to access your server.

Then go to localhost to see a list of running instances (it will be empty since you haven't added any yet).

If you want to use boto with this (using the simpler decorators above instead is strongly encouraged), the easiest way is to create a boto config file (~/.boto) with the following values:

o]
ecure = False
s_validate_certificates = False
y_port = 5000
y = 127.0.0.1

If you want to use boto3 with this, you can pass an endpoint_url to the resource

3.resource(
service_name='s3',
region_name='us-west-1',
endpoint_url='http://localhost:5000',

Install
p install moto

This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.