NAME

Test::Collectd::Plugins - Common out-of-band collectd plugin test suite

VERSION

Version 0.1008

SYNOPSIS

use Test::More;
use Test::Collectd::Plugins typesdb => ["/usr/share/collectd/types.db"];

plan tests => 4;

load_ok ("Collectd::Plugins::Some::Plugin");
read_ok ("Collectd::Plugins::Some::Plugin", "plugin_name_as_returned_by_dispatch");
read_config_ok ("My::Plugin", "my_plugin", "/path/to/my_plugin.conf");

my $expected = [[{{ plugin => "my_plugin", type => "gauge", values => [ 42 ] }}]];
my $got = read_values_config ("My::Plugin", "my_plugin", "/path/to/my_plugin.conf");

is_deeply ($got, $expected);

done_testing;

Testing collectd modules outside of collectd's perl interpreter is tedious, as you cannot simply 'use' them. In fact you can't even 'use Collectd', try it and come back. This module lets you test collectd plugins outside of the collectd daemon. It is supposed to be the first step in testing plugins, detecting syntax errors and common mistakes. There are some caveats (see dedicated section), and you should use the usual collectd testing steps afterwards e.g. enabling debug at compile time, then running the collectd binary in the foreground while using some logging plugin, plus some write plugin. I usually use logfile to STDOUT and csv plugin.

MODULE vs. PLUGIN

Most methods will accept either $plugin or $module or both. They correspond to collectd-perl's LoadPlugin $module and Plugin $plugin respectively. It's easy to mistake one for the other. While $module is as its name suggests the perl module's name, $plugin corresponds to the collectd plugin's name, as called by plugin_dispatch_values. This difference makes it possible for a plugin to dispatch values on behalf of another, or to register multiple plugins. Make sure you ask the methods the right information.

SUBROUTINES/METHODS

load_ok <$module> <$message>

Tries to load the plugin module. As collectd-perl plugin modules contain direct calls (upon loading) to "plugin_register" in Collectd, the former are intercepted by FakeCollectd which is part of this distribution. This has the effect of populating the %FakeCollectd hash. See FakeCollectd for more info.

plan tests => $num

See "plan" in Test::More.

read_ok <$module> <$plugin> [$message]

Loads the plugin module identified by $module, then tries to fire up the registered read callback for this plugin ($plugin), while intercepting all calls to "plugin_dispatch_values" in Collectd, storing its arguments into the %FakeCollectd hash. The latter are checked against the following rules, which match the collectd guidelines:

  • There shall be only one and only one hashref argument

  • The following keys are mandatory: plugin, type, values

  • Only the following keys are valid: plugin, type, values, time, interval, host, plugin_instance, type_instance.

  • The key type must be present in the types.db file.

  • The key values must be an array reference and the number of elements must match its data type in module's configuration option types.db.

  • All other keys must be scalar strings with at most 63 characters: plugin, type, host, plugin_instance and type_instance.

  • The keys time and interval must be a positive integers.

  • The keys host, plugin_instance and type_instance may use all ASCII characters except "/".

  • The keys plugin and type may use all ASCII characters except "/" and "-".

read_config_ok <$module> <$plugin> <$config> [$message]

Same as read_ok but also reads configuration from $plugin_config and fires up the configuration callback of plugin $plugin_module. "parse" in Test::Collectd::Config will kindly format a configuration file or handle to suit this subroutine.

read_values (module, plugin, [ config ])

Returns arrayref containing the list of arguments passed to "plugin_dispatch_values" in Collectd. Example:

[
 # first call to L<Collectd/plugin_dispatch_values>
 [
  { plugin => "myplugin", type => "gauge", values => [ 1 ] },
 ],
 # second call to L<Collectd/plugin_dispatch_values>
 [
  { plugin => "myplugin", type => "gauge", values => [ 2 ] },
 ],
]

A config hash can be provided for plugins with a config callback. The format of this hash must be the same as the one described in collectd-perl's manpage (grep for "Config-Item"). Use "parse" in Test::Collectd::Config for conveniently yielding such a hash from a collectd configuration file. Only the section concerning the plugin should be provided, e.g. without all global collectd config sections.

CAVEATS

FakeCollectd

This module tricks the tested collectd plugins into loading FakeCollectd instead of Collectd, and replaces calls thereof by simple functions which populate the %FakeCollectd:: hash in order to store its arguments. As it uses the name of the calling plugin module for its symbols, subsequent calls to the test subs are not really independant, which is suboptimal especially for a test module. If you have a saner solution to do this, please let me know.

methods

Replacements for most common Collectd::Plugins methods are implemented, as well as constants. We may have missed some or many, and as new ones are added to the main collectd tree, we will have to keep up to date.

config

Although "parse" in Test::Collectd::Config has been a straight port of liboconfig (which itself is using lex/yacc) to Parse::Yapp/Parse::Lex, you might get different results in edge cases.

types.db

If no types.db list is being specified during construction, the object will try to use the shipped version. Also, if a list is given, the first appearance of the type will be used; this may differ from collectd's mechanism.

SEE ALSO

FakeCollectd, http://collectd.org/wiki/index.php/Naming_schema

AUTHOR

Fabien Wernli, <wernli_workingat_in2p3.fr>

BUGS

Please report any bugs or feature requests to https://github.com/faxm0dem/Test-Collectd-Plugins/issues.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Test::Collectd::Plugins

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright 2012 Fabien Wernli.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.