Stelligent

AWS Integration Testing for boto with potemkin-decorator

Test Automation for Integrating with External Services

Developing test automation code for an interface to an “external” service is always a difficult proposition.  There is a spectrum of techniques for developing reproducible tests against an external service. On one end of the spectrum are “mocking” techniques and on the other far end of the spectrum are “live” integration tests involving the actual external service.

Test Automation for boto

The boto library is a (python) client library for interfacing with AWS services.  Developing test automation code for boto code has the same difficulties as integration testing for an external service.  In effect, an AWS service is the “external service”.

The spectrum of techniques for testing boto code from least realistic to most includes:

Benefits and Drawbacks

Each one of these techniques can provide valuable feedback, but then also have trade-offs.

Mocking/Stubbing

Benefits

Drawbacks

Simulation

Benefits

Drawbacks

Live Testing

Benefits

Drawbacks

Initial Conditions in Live AWS Integration Testing

While there are many drawbacks to live AWS integration testing to consider, there comes a time when it is necessary.  Especially as a developer is first experimenting with a given AWS service, observing how the service actually behaves is critical.

The potemkin-decorator attempts to address the difficulties of setting up initial conditions for live integration tests.  Instead of having to set up the initial conditions by writing boto code that is possibly as complex as the code under test, it allows capturing initial conditions as a CloudFormation template.  CloudFormation is a far simpler “language” to develop in than boto.

For example, in developing boto code that operates on an S3 bucket, the following CloudFormation template could capture the initial conditions:

See the gist on github.

The following pytest code invokes the potemkin.CloudFormationStack decorator.

  1. It invokes CreateStack on the aes256_bucket.yml template with the specified dictionary of Parameter values.
  2. It creates a stack that starts with the name TestStack and ends with a timestamp suffix.  The full name is wired into the pytest method as the stack_name argument so that the stack resources can be queried.
  3. The stack outputs from CreateStack are turned into a vanilla dictionary and wired into the test method as the stack_outputs argument.
  4. The test method is called.  From here, the test code can expect the bucket exists, operate upon it, and make assertions about the outcomes of the operations.
  5. The stack is torn down.

See the gist on github.

To execute this test, first:

Then:

See the gist on github.

AWS Config Rule Testing

Developing test automation for AWS Config Rules has similar challenges to developing arbitrary boto code.  The first way to test rule code is to separate the business logic for the rule from any calls to boto and to test it in isolation (i.e. mocking/stubbing).  That said, given a need to do a “live” test on an AWS Config Rule for ultimate confirmation, potemkin-decorator can be used to set up compliant or non-compliant resources for the test.

An additional complexity in doing live testing with AWS Config is that rules run asynchronously.  The API includes a call to start the evaluation of a given rule but it does not return the results synchronously.  Further, just because Config Service reports a rule evaluation was successful after a resource was created, that doesn’t guarantee the resource was actually evaluated (for internal rules vice custom rules).  Therefore, a live test must wait/poll for the given resource to appear in the results before asserting compliance or non-compliance.  The potemkin-decorator component includes a helper method (evaluate_config_rule_and_wait_for_resource) for invoking AWS Config Rules and waiting for the results.

For example, in testing the eip-attached Config Rule, the following CloudFormation template creates a non-compliant Elastic IP resource:

See the gist on github.

The following pytest code invokes the potemkin.CloudFormationStack decorator.

  1. It invokes CreateStack on the template to create the unattached Elastic IP.
  2. The stack outputs from CreateStack are turned into a vanilla dictionary and wired into the test method – the resource ID for the EIP.
  3. The test method is called.  From here, the test code invokes the eip-attached Config Rule and waits until the newly created resource appears in the detailed results for that rule.
  4. The test asserts that the EIP is non-compliant.
  5. The stack is torn down.

See the gist on github.

Conclusion

Testing boto code can be difficult, but there are many techniques that can be applied to ensure quality software.  Live “integration testing” with AWS should most likely be done sparingly, but when it becomes necessary, potemkin-decorator can help improve developer velocity.

Stelligent Amazon Pollycast