The SSH Monitoring ZenPacks include an unit-testing framework that is easily extensible with the command output from various hosts. This extensibility can be used to add command output found in the field that trigger issues in the parsers.
Each SSH Monitoring ZenPack has a testPlugins.py
and testParsers.py
file in its tests
directory. These test scripts walk the plugindata
and parserdata
directories to find test data.
To create a new test you need to create a new directory with the name of the host under the appropriate test data directory (e.g. tests/plugindata/aix/test-aix61
). In that new directory place two files. Both files share the same name; one has no extension and the other has a .py
extension.
The file with no extension must contain the command on the first line, and the output of the command on the subsequent lines. The file with the .py
extension contains a Python dictionary with expected values that were manually parsed from the command output. The format of these dictionaries is slightly different depending on the type of test (modeling plugin or data point parser). The formats will be covered in sections later in this document.
If you are adding the first test data files for a parser, then you must edit testPlugins.py
or testParsers.py
to import the parser module and add the module to the list of tested modules.
Multiple modeling plugins can parse the same command. The first level of keys in the dictionary is the name of the modeling plugin class.
Modeling plugins can return values of the following types (which are defined in $ZENHOME/Products
):
ObjectMap
RelationshipMap
List of the above data map classes
The test data for each of these return types is in different formats.
The test data is formatted as a simple dictionary that maps the attribute names of that ObjectMap
to the expected values.
{ "lsps_s": # the parser {"totalSwap": 536870912} }
RelationshipMaps
contain many ObjectMaps
. The test data is formatted as a two-level nested dictionary. The first level of keys is the ID that identifies the ObjectMap
under test. The second level dictionary maps the attribute names of that ObjectMap
to the expected values.
{ "lslpp": { # the parser "ICU4C.rte 6.1.0.0": dict( setProductKey=("ICU4C.rte 6.1.0.0", "IBM"), setDescription="International Components for Unicode", setInstallDate="2008/12/16 13:56:29", ), "Java5.sdk 5.0.0.130": dict( setProductKey=("Java5.sdk 5.0.0.130", "IBM"), setDescription="Java SDK 32-bit", setInstallDate="2008/12/16 14:22:26", ), "cdrecord 1.9-7": dict( setProductKey=("cdrecord 1.9-7", "IBM"), setDescription="A command line CD/DVD recording program.", setInstallDate="2008/12/16 19:17:11", ), }, }
The test data is formatted as a list of dictionaries. The dictionaries are flat for ObjectMaps
or two-level nested for RelationshipMaps
.
{ "prtconf": # the parser [ {"setHWProductKey": ("9114-275", "IBM"), "setHWSerialNumber": "10E03AE"}, {"proc1": dict( clockspeed=1000, cacheSizeL2=1536, setProductKey=('PowerPC POWER4, 64-bit, 1000 MHz', 'IBM'),),}, {"totalMemory": 2147483648} ], }
Data point parsers differ in their return values. They can either return device-level data points or component data points. The test data is formatted differently based on the return type of the parser.
The test data for a device-level parser is formatted as a simple dictionary. The keys are the IDs of the data points returned by the parser.
{ "read": 171409 * 1024, "written": 530600 * 1024, }
The test data for a component parser is formatted as a two-deep nested dictionary. The first-level keys are the IDs of the components under test. The second-level dictionary maps the IDs of the data points to the expected values.
{ '/': dict( totalBlocks=131072, usedBlocks=108052, availBlocks=23020, percentUsed=83, usedInodes=7505, availableInodes=5962, percentInodesUsed=56, ), '/opt': dict( totalBlocks=131072, usedBlocks=84496, availBlocks=46576, percentUsed=65, usedInodes=1645, availableInodes=10753, percentInodesUsed=14, ), }
To run all the tests in a ZenPack Use the last part of the ZenPack name
runtests --type unit AixMonitor
To run a single test
runtests --type unit --name testAixPlugins AixMonitor
You might notice that tests are run redundantly from the build
directory of the ZenPack in addition to being run from the source directory. To keep this from happening do the following:
find build -name tests -delete