Developer's Guide

  • Docs Home
  • Community Home

8. Adding SSH Monitoring Tests

8.1. Overview

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.

Note

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.

8.2. Modeling Plugin Test Data

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.

8.2.1. Test Data for an ObjectMap

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}
}

8.2.2. Test Data for a RelationshipMap

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",
	        ),

	    },
}

8.2.3. Test Data for a List of Data Maps

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}
	    ],
}

8.3. Data Point Parser Test Data

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.

8.3.1. Test Data for Device-Level Parsers

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,
}

8.3.2. Test Data for Component Parsers

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,
	    ),
}

8.4. Running the Tests

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