apama-analytics-builder-block-sdk

Testing blocks

Blocks can be tested using the PySys testing framework. This is included in the Apama installation, along with extensions for using Apama with PySys. Built on top of the Apama extensions is a framework to test blocks. Refer to the Apama Python API documentation.

The samples include tests. The pysystestproject.xml configuration relies on the environment variable ANALYTICS_BUILDER_SDK being set to the location of the block SDK using an absolute path. PySys tests should contain a run.py with a class that extends apama.analyticsbuilder.basetest:AnalyticsBuilderBaseTest. In the execute method of the test, start a correlator with the self.startAnalyticsBuilderCorrelator() method. This starts a correlator, injects the Analytics Builder framework into it, and returns a CorrelatorHelper object. Provide a blockSourceDir parameter with the path to the source of the blocks, typically within the project tree (use self.project.SOURCE from the supplied pysysproject.xml file). Then, create a model to test the block with the self.createTestModel('<blockUnderTest>') This results in a model being activated in the correlator with an input and output connected to every input and output of the block, and an identifier of the model is returned. The block can be exercised by sending events created by the self.inputEvent method, for a given block input identifier.

Both createTestModel and inputEvent take an optional argument: id - an identifier of the model. If an identifier is not specified, createModel will use the identifiers model_0 and upwards, and inputEvent will use model_0 (that is, the first created model).

createTestModel takes these arguments:

The following methods can be used to check the output of the block is as expected (unless the output has been mapped to None or an empty string):

Note that the correlator started by startAnalyticsBuilderCorrelator is externally clocked, meaning that the correlator’s time increments only when a timestamp event is received. Consequently, events arriving between timestamp events are assigned the same time, that is, the time of the last timestamp.

After a timestamp is received, subsequent events are held until the next timestamp event that has a time at least 0.1s greater. All of the events are then processed together. If a value for a particular input is received while an event for that input is already waiting, only one of the events will be retained and then sent to the model. The other value will be discarded. (Whether this is the new value or the existing, waiting value is undefined.)

The timestamp method can be used to generate a time pseudo-event when testing. If events modifying multiple inputs are sent to the model between timestamps (and those timestamps are at least 0.1 seconds apart), the new values will be received by the model simultaneously and evaluated once. For an example of this, see the GroupStatistics_Bounded test sample in the in the samples/tests directory.

For example, a simple test is:

from pysys.constants import *
from apamax.analyticsbuilder.basetest import AnalyticsBuilderBaseTest

class PySysTest(AnalyticsBuilderBaseTest):
    def execute(self):
        correlator = self.startAnalyticsBuilderCorrelator(
            blockSourceDir=f'{self.project.SOURCE}/blocks/')
        modelId = self.createTestModel('apamax.analyticsbuilder.samples.Offset')
        self.sendEventStrings(correlator,
                              self.timestamp(1),
                              self.inputEvent('value', 100.75, id=modelId),
                              self.timestamp(2),
                              self.inputEvent('value', 10.50, id=modelId),
                              self.timestamp(2.1),
                              )

    def validate(self):
        self.assertBlockOutput('output', [200.75, 110.50])

And will generate outputs at times 1 and 2, but the self.timestamp(2.1) is required to trigger the events at time 2.

Points to be aware of:

For examples, see the tests in the samples/tests directory.

< Prev: Building a block into an extension Contents Next: Parameters, block startup and error handling >