SPARKL is a middleware connecting services and applications. They communicate through events and all the events are logged.

I am going to show you how to use these logs for testing integrated systems.

The SPARKL configuration we are going to test synchronizes two or more file directories across one or more machines.

You may watch a short demonstation here.

One way to test such a configuration would be to check the file systems. This, however, would be quite complicated to do across machines.

Instead of checking the actual directories we validate the events that drive the file system manipulations.

Dependencies

  • The Python pytest library
  • The SPARKL CLI Python library

Objectives

  • Create a connection to SPARKL
  • Import the demo configuration into our SPARKL user tree
  • Create a master directory where we create, delete and move files
  • Create a slave directory that follows changes to the master
  • Connect the SPARKL services to their Python implementations
  • Subscribe to SPARKL events and filter them

The basic setup

  1. Create a per session test setup that connects to SPARKL, logs you in, and imports the test configuration.
  2. Use environment variables or a settings file to specify the constants:
    • SPARKL_URL - the URL of your SPARKL instance
    • SPARKL_USER - your SPARKL user name
    • SPARKL_PASS - your password
    • FILE_SYNC_XML - the path - or URL - to the FileSync SPARKL configuration
    If you don't have the demo file locally, use this URL.
  3. Create a master directory where you create, delete or move files.
  4. Create a slave directory that mirrors changes to the master. You can use the setup method to create the directories. For example, use the tempfile.mkdtemp() method.
  5. Map the Python implementation modules - master.py and slave.py - to the services in the configuration. Use the sparkl service SERVICE MODULE --path PATH command to do that.

    To connect the implementation modules we need to change to the test directories allocated for the file system events. For example, to start the master module, we change to the directory where we want to create or move files and start the slave module in the directory where we want these changes mirrored.

  6. Send the paths to the two file system directories to the actual test using the yield keyword. Each test that uses setup_method can access the paths to the master and slave directories.
  7. Add a teardown method that cleans up after all tests are run.

    The teardown removes the SPARKL configuration from the user tree, closes the connection to SPARKL and may remove the test directories on your file system too.

The listener setup

We want to listen to the events generated during the test. We need a special setup that starts the SPARKL listener in a separate process.

  1. In the same conftest.py file create the listener setup. It is run once per test session. The listener communicates with the tests using a queue. Let’s create it too.
  2. The listener process places the events in the queue we’ve just created.

    The start_listener function starts the SPARKL listener and listens to events generated within the FileSync configuration’s folder in the user tree. Each event is placed in the provided queue.

    Use time.sleep/1 to give the process time to come up properly.
  3. Offer event_queue to the tests and stop the listener process once all tests are run.

The actual test

We are looking for a set of events. The creation of a file in the master directory should cause the following:

  • A Put notify invoked by the Master service
  • A Put consume implemented by the Slave service
  1. Create the test and specify the setup methods as its parameters. The order of the setups is important. setup_method must come before listener_setup as the listener needs a connection to SPARKL.
  2. Gather the paths to the test directories and the event queue from the test setups.
  3. Create a file in the master directory and give the configuration time to clone the file in the slave directory.

    We use the same context manager as in conftest.py to change to the master directory, create foo.txt and return to the original directory.

  4. Let’s collect the events to find out what happened.
  5. We use a loop to go through the events that happen after the creation of foo.txt. The loop breaks when a certain condition is met or if no new event arrives for 3 seconds.
  6. Let’s specify a break condition.

    We want both a specific notify and a specific consume event to happen. The test only succeeds if both of them happen before the loop breaks on a timeout. Each event is a Python struct. The tag of the event - event[‘tag’] is the type of the event. For example, request, reply or error. Use this tag to retrieve the full path to the event - event[‘attr’][‘notify’]. The full path ends with the actual name of the event.

This is a shortened, simplified version of the original test. The original uses the SPARKL event-based test framework. Have a look if interested.

Miklos Duma

Miklos Duma

Not all who wander are lost