It's been several weeks since I first announced amulet[0] and I'm happy to
release the "1.0" milestone of amulet. A lot has been added since the
simple `jitsu watch` port. However, before I go into the details of this
release I want to take this moment to describe really the aim of this
project.

Amulet is designed as a testing harness for Juju Functional Tests (tests
executed with the `juju test` plugin). These tests are designed to run the
charm, on actually bootstrapped environments, in order to insure your charm
works as you expect it to in a live environment. This type of testing is a
step up from just unit-testing your code and follows the same line as
integration testing.

Currently, tests can be executed now, but you only have the ability to
interact with services via `juju ssh` and then collect output of the log
files for analysis. With Amulet, you'll be able to drive the service from
within the test, collect information while the environment is running, and
then potentially influence change from this information while the test is
still running.

In the spirit of Juju Charms being language agnostic, Amulet is designed to
work within the scope of the `juju test` function but is not the only means
by which you can write functional tests. Instead, as a harness, it's
designed to allow you greater flexibility and control over your tests.
While this release is only available as a Python module, future releases
will provide an agnostic programmable API (much like in the second version
of charm-helpers) to allow languages other than Python to leverage the
Amulet testing harness.

In a sentence, Amulet is to tests as charm-helpers are to hooks; a tool set
to make the writing of said task easier and more predictable.

What can Amulet actually do? When used to it's full potential, Amulet
provides an abstraction layer to juju-deployer to simplify deployer
instructions and also provides a service called "sentries" which provide
deeper inspection of services and relations. At this time Amulet is able to
query files and directories on a remote unit, if/when all running hooks in
the environment cease (true "wait" support), allow the tester to run
arbitrary commands on a unit, and will collect the data sent between units
during relation hooks.

With these tools, a test can further drill down in to the deployed
environment to better insure the charm functions as expected when plugged
in to the other services it depends on.

The changes in this release are outlined below:

# Deployment

Juju Deployer is now integrated with Amulet. You can choose to either
describe your deployment via the abstraction layer or simply load an
existing deployer json/yaml config.

eg:

import amulet

d = amulet.Deployment()
d.add('mysql')
d.add('wordpress')
d.relate('wordpress:db', 'mysql:db')
d.setup(timeout=600)


## Sentries

If you're using deployer integration, you'll automatically get sentry
support (unless disabled). Sentries are subordinate charms that are created
on-the-fly for each service deployed. They collect information about the
services running and allow for deeper probing of units via an exposed API.


import amulet

d = amulet.Deployment()
d.add('mysql')
d.add('wordpress')
d.relate('wordpress:db', 'mysql:db')
d.setup(timeout=600)

d.sentry.unit['wordpress/0'].file_contents('/var/www/wp-info.php')
d.sentry.unit['mysql/0'].relation('db', 'wordpress:db')
d.sentry.unit['wordpress/0'].run('service php-fpm stop')

## Wait

Wait will continue to work as expected before; however, if you've used
deployer with sentries it'll check to insure a service is actually started
by checking for currently running hooks on each unit. This allows for more
accurate control when waiting for an environment to be completely set up.

import amulet

d = amulet.Deployment()
d.add('mysql')
d.add('wordpress')
d.relate('wordpress:db', 'mysql:db')

# Setup runs juju-deployer, which will end if all units are started, not
when all hooks are done executing.
d.setup(timeout=600)

# Wait will constantly query all units until there are no more hooks being
executed in the environment or a timeout threshold is met.
d.sentry.wait(timeout=300)


There are several other additions, the ability to build charms on-the-fly
as well as a rudimentary charmstore abstraction. These will be further
documented in the juju docs under the Amulet Developer Reference section.

As this is a first cut release, if you find any bugs please use LP to
report them (lp:amulet). Amulet is being packaged in ppa:juju/stable and
will be available soon for installation.


0: https://lists.ubuntu.com/archives/juju/2013-July/002658.html
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju

Reply via email to