line  
 stmt  
 bran  
 cond  
 sub  
 pod  
 time  
 code  
 
1 
 
  
 
   
 
 
 
 
 
 
 
 
 
 
 
 package Test::Collectd::Plugins;  
 
2 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
3 
 
5
 
 
 
 
 
  
5
   
 
 
 
164415
 
 use 5.006;  
 
  
 
5
 
 
 
 
 
 
 
 
 
12
 
    
 
4 
 
5
 
 
 
 
 
  
5
   
 
 
 
18
 
 use strict;  
 
  
 
5
 
 
 
 
 
 
 
 
 
6
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
103
 
    
 
5 
 
5
 
 
 
 
 
  
5
   
 
 
 
16
 
 use warnings;  
 
  
 
5
 
 
 
 
 
 
 
 
 
8
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
115
 
    
 
6 
 
5
 
 
 
 
 
  
5
   
 
 
 
14
 
 use Carp qw(croak cluck);  
 
  
 
5
 
 
 
 
 
 
 
 
 
6
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
259
 
    
 
7 
 
5
 
 
 
 
 
  
5
   
 
 
 
2117
 
 use namespace::autoclean;  
 
  
 
5
 
 
 
 
 
 
 
 
 
63494
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
17
 
    
 
8 
 
5
 
 
 
 
 
  
5
   
 
 
 
2330
 
 use Test::Collectd::Config qw(parse);  
 
  
 
5
 
 
 
 
 
 
 
 
 
20
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
358
 
    
 
9 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
10 
 
5
 
 
 
 
 
  
5
   
 
 
 
2542
 
 BEGIN {use Package::Alias Collectd => "FakeCollectd"}  
 
  
 
5
 
 
 
 
 
 
 
 
 
2054
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
24
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
1095
 
    
 
11 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
12 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 NAME  
 
13 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
14 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Test::Collectd::Plugins - Common out-of-band collectd plugin test suite  
 
15 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
16 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 VERSION  
 
17 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
18 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Version 0.1008  
 
19 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
20 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
21 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
22 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our $VERSION = '0.1009';  
 
23 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
24 
 
5
 
 
 
 
 
  
5
   
 
 
 
7
 
 use base 'Test::Builder::Module';  
 
  
 
5
 
 
 
 
 
 
 
 
 
1125
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
16834
 
    
 
25 
 
5
 
 
 
 
 
  
5
   
 
 
 
5
 
 use IO::File;  
 
  
 
5
 
 
 
 
 
 
 
 
 
3053
 
    
 
  
 
5
 
 
 
 
 
 
 
 
 
22
 
    
 
26 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
27 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our @EXPORT = qw(load_ok read_ok read_config_ok read_values $typesdb);  
 
28 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
29 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our $typesdb;  
 
30 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
31 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub import_extra {  
 
32 
 
4
 
 
 
 
 
  
4
   
 
  
1
   
 
3
 
 	my $class = shift;  
 
33 
 
4
 
 
 
 
 
 
 
 
 
5
 
 	my $list = shift;  
 
34 
 
4
 
 
 
 
 
 
 
 
 
14
 
 	my $args;  
 
35 
 
4
 
  
 50
   
 
 
 
 
 
 
 
5
 
 	$args = @$list == 1 ? $list->[0] : {@$list};  
 
36 
 
4
 
 
 
 
 
 
 
 
 
31
 
 	@$list = ();  
 
37 
 
4
 
  
 50
   
 
  
 33
   
 
 
 
 
 
10
 
 	croak __PACKAGE__." can receive either a hash or a hash reference."  
 
38 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		unless ref $args and ref $args eq "HASH";  
 
39 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 	for (keys %$args) {  
 
40 
 
  
0
   
 
  
  0
   
 
 
 
 
 
 
 
0
 
 		if (/^typesdb$/i) {  
 
41 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 			$typesdb = $args->{$_};  
 
42 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		} else {  
 
43 
 
4
 
 
 
 
 
 
 
 
 
9
 
 			push @$list, $_ => $args->{$_};  
 
44 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
45 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
46 
 
16
 
 
 
 
 
 
 
 
 
9218
 
 	return;  
 
47 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
48 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
49 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 SYNOPSIS  
 
50 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
51 
 
 
 
 
 
 
 
 
 
 
 
 
 
   use Test::More;  
 
52 
 
 
 
 
 
 
 
 
 
 
 
 
 
   use Test::Collectd::Plugins typesdb => ["/usr/share/collectd/types.db"];  
 
53 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
54 
 
 
 
 
 
 
 
 
 
 
 
 
 
   plan tests => 4;  
 
55 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
56 
 
 
 
 
 
 
 
 
 
 
 
 
 
   load_ok ("Collectd::Plugins::Some::Plugin");  
 
57 
 
 
 
 
 
 
 
 
 
 
 
 
 
   read_ok ("Collectd::Plugins::Some::Plugin", "plugin_name_as_returned_by_dispatch");  
 
58 
 
 
 
 
 
 
 
 
 
 
 
 
 
   read_config_ok ("My::Plugin", "my_plugin", "/path/to/my_plugin.conf");  
 
59 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
60 
 
 
 
 
 
 
 
 
 
 
 
 
 
   my $expected = [[{{ plugin => "my_plugin", type => "gauge", values => [ 42 ] }}]];  
 
61 
 
 
 
 
 
 
 
 
 
 
 
 
 
   my $got = read_values_config ("My::Plugin", "my_plugin", "/path/to/my_plugin.conf");  
 
62 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
63 
 
 
 
 
 
 
 
 
 
 
 
 
 
   is_deeply ($got, $expected);  
 
64 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
65 
 
 
 
 
 
 
 
 
 
 
 
 
 
   done_testing;  
 
66 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
67 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Testing collectd modules outside of collectd's perl interpreter is tedious, as you cannot  
 
68 
 
 
 
 
 
 
 
 
 
 
 
 
 
 simply 'use' them. In fact you can't even 'use Collectd', try it and come back.  
 
69 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This module lets you test collectd plugins outside of the collectd daemon. It is supposed  
 
70 
 
 
 
 
 
 
 
 
 
 
 
 
 
 to be the first step in testing plugins, detecting syntax errors and common mistakes.   
 
71 
 
 
 
 
 
 
 
 
 
 
 
 
 
 There are some caveats (see dedicated section), and you should use the usual collectd testing  
 
72 
 
 
 
 
 
 
 
 
 
 
 
 
 
 steps afterwards e.g. enabling debug at compile time, then running the collectd binary in  
 
73 
 
 
 
 
 
 
 
 
 
 
 
 
 
 the foreground while using some logging plugin, plus some write plugin. I usually use logfile  
 
74 
 
 
 
 
 
 
 
 
 
 
 
 
 
 to STDOUT and csv plugin.  
 
75 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
76 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 MODULE vs. PLUGIN  
 
77 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
78 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Most methods will accept either $plugin or $module or both. They correspond to C's C and C 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.     
 
79 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
80 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 SUBROUTINES/METHODS  
 
81 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
82 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 load_ok <$module> <$message>  
 
83 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
84 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Tries to load the plugin module. As collectd-perl plugin modules contain direct calls (upon loading) to L, the former are intercepted by L which is part of this distribution. This has the effect of populating the %FakeCollectd hash. See L for more info.     
 
85 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
86 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
87 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
88 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub load_ok ($;$) {  
 
89 
 
16
 
 
 
 
 
  
16
   
 
  
1
   
 
69
 
 	my $module = shift;  
 
90 
 
16
 
 
 
  
100
   
 
 
 
 
 
26
 
 	my $msg = shift || "load OK";  
 
91 
 
16
 
 
 
 
 
 
 
 
 
250
 
 	_load_module($module);  
 
92 
 
40
 
 
 
 
 
 
 
 
 
40
 
 	__PACKAGE__->builder->is_eq($@, "", $msg);  
 
93 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
94 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
95 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _load_module ($) {  
 
96 
 
40
 
 
 
 
 
  
40
   
 
 
 
2324
 
 	my $module = shift;  
 
97 
 
22
 
 
 
 
 
 
 
 
 
54
 
 	eval "require $module";  
 
98 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
99 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
100 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _init_plugin ($) {  
 
101 
 
22
 
  
 50
   
 
 
 
  
22
   
 
 
 
54
 
 	my $plugin = shift or die "_init_plugin needs plugin name";  
 
102 
 
22
 
 
 
 
 
 
 
 
 
42
 
 	my $init = $FakeCollectd{$plugin}->{Callback}->{Init};  
 
103 
 
4
 
  
100
   
 
 
 
 
 
 
 
189
 
 	if (defined $init) {  
 
104 
 
18
 
 
 
 
 
 
 
 
 
25
 
 		eval "$init()";  
 
105 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	} else {  
 
106 
 
4
 
 
 
 
 
 
 
 
 
35
 
 		return 1;  
 
107 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
108 
 
  
0
   
 
  
 50
   
 
 
 
 
 
 
 
0
 
 	if ($@) {  
 
109 
 
4
 
 
 
 
 
 
 
 
 
10
 
 		return undef;  
 
110 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	} else {  
 
111 
 
4
 
 
 
 
 
 
 
 
 
11
 
 		return $init;  
 
112 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
113 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
114 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
115 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _read ($) {  
 
116 
 
4
 
  
 50
   
 
 
 
  
4
   
 
 
 
7
 
 	my $plugin = shift or die "_read needs plugin name";  
 
117 
 
4
 
 
 
 
 
 
 
 
 
12
 
 	my $reader = $FakeCollectd{$plugin}->{Callback}->{Read};  
 
118 
 
4
 
  
 50
   
 
 
 
 
 
 
 
222
 
 	if (defined $reader) {  
 
119 
 
4
 
 
 
 
 
 
 
 
 
66
 
 		eval "$reader()";  
 
120 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 		return $reader;  
 
121 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	} else {  
 
122 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 		eval { die "_read: No reader defined for plugin `$plugin'" };  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
    
 
123 
 
8
 
 
 
 
 
 
 
 
 
12
 
 		return undef;  
 
124 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
125 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
126 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
127 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _reset_values ($) {  
 
128 
 
8
 
 
 
 
 
  
8
   
 
 
 
24
 
 	my $plugin = shift;  
 
129 
 
4
 
  
100
   
 
 
 
 
 
 
 
4
 
 	if (exists $FakeCollectd{$plugin}->{Values}) {  
 
130 
 
4
 
 
 
 
 
 
 
 
 
13
 
 		undef @{$FakeCollectd{$plugin}->{Values}};  
 
  
 
8
 
 
 
 
 
 
 
 
 
16
 
    
 
131 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
132 
 
4
 
 
 
 
 
 
 
 
 
13
 
 	return 1;  
 
133 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
134 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
135 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _values ($) {  
 
136 
 
4
 
  
 50
   
 
 
 
  
4
   
 
 
 
14
 
 	my $plugin = shift or die "_values needs plugin name";  
 
137 
 
4
 
  
 50
   
 
 
 
 
 
 
 
4
 
 	if (exists $FakeCollectd{$plugin}->{Values}) {  
 
138 
 
4
 
 
 
 
 
 
 
 
 
13
 
 		return @{$FakeCollectd{$plugin}->{Values}}  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
    
 
139 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	} else {  
 
140 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		return undef  
 
141 
 
4
 
 
 
 
 
 
 
 
 
10
 
 	}  
 
142 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
143 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
144 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _config ($$) {  
 
145 
 
4
 
  
 50
   
 
 
 
  
4
   
 
 
 
11
 
 	my $plugin = shift or die "_config(plugin,config)";  
 
146 
 
4
 
  
 50
   
 
 
 
 
 
 
 
8
 
 	my $cfg = shift or die "_config(plugin,config)";  
 
147 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
148 
 
4
 
 
 
 
 
 
 
 
 
8
 
 	my $cb = $FakeCollectd{$plugin}->{Callback}->{Config};  
 
149 
 
  
0
   
 
  
 50
   
 
 
 
 
 
 
 
0
 
 	unless ($cb) {  
 
150 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 		eval {croak "plugin $plugin does not provide a config callback"};  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
    
 
151 
 
4
 
 
 
 
 
 
 
 
 
13
 
 		return undef;  
 
152 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
153 
 
4
 
  
 50
   
 
 
 
 
 
 
 
7
 
 	my $config = Test::Collectd::Config::parse($cfg) or croak "failed to parse config";  
 
154 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	# this fires up the plugin's config callback with provided config  
 
155 
 
5
 
 
 
 
 
  
5
   
 
 
 
6
 
 	eval {no strict "refs"; &$cb($config)}; # or croak("config callback $cb failed: $@");  
 
  
 
5
 
 
 
 
 
 
 
 
 
5426
 
    
 
  
 
4
 
 
 
 
 
 
 
 
 
135
 
    
 
  
 
4
 
 
 
 
 
 
 
 
 
18
 
    
 
  
 
4
 
 
 
 
 
 
 
 
 
43
 
    
 
156 
 
  
0
   
 
  
 50
   
 
 
 
 
 
 
 
0
 
 	if ($@) {  
 
157 
 
4
 
 
 
 
 
 
 
 
 
14
 
 		return undef;  
 
158 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	} else {  
 
159 
 
4
 
 
 
 
 
 
 
 
 
723
 
 		return $config;  
 
160 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
161 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
162 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
163 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 plan tests => $num  
 
164 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
165 
 
 
 
 
 
 
 
 
 
 
 
 
 
 See L.   
 
166 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
167 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
168 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
169 
 
 
 
 
 
 
 
 
 
 
 
 
 
 #sub plan { __PACKAGE__ -> builder -> plan (@_) }  
 
170 
 
 
 
 
 
 
 
 
 
 
 
 
 
 #sub diag { __PACKAGE__ -> builder -> diag (@_) }  
 
171 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
172 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 read_ok <$module> <$plugin> [$message]  
 
173 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
174 
 
 
 
 
 
 
 
 
 
 
 
 
 
 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 L, storing its arguments into the %FakeCollectd hash. The latter are checked against the following rules, which match the collectd guidelines:   
 
175 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
176 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 2  
 
177 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
178 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
179 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
180 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub read_ok ($$;$) {  
 
181 
 
4
 
 
 
 
 
  
4
   
 
  
1
   
 
6
 
 	my $module = shift;  
 
182 
 
4
 
 
 
 
 
 
 
 
 
13
 
 	my $plugin = shift;  
 
183 
 
4
 
 
 
  
 50
   
 
 
 
 
 
18
 
 	my $msg = shift || "read OK";  
 
184 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
185 
 
4
 
 
 
 
 
 
 
 
 
62
 
 	my $tb = __PACKAGE__->builder;  
 
186 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
187 
 
 
 
 
 
 
 
 
 
 
 
 
 
 $tb -> subtest($msg, sub {  
 
188 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
189 
 
4
 
  
 50
   
 
 
 
  
4
   
 
 
 
1267
 
 	$tb -> ok (_load_module($module), "load plugin module") or $tb -> diag ($@);  
 
190 
 
4
 
  
 50
   
 
 
 
 
 
 
 
937
 
 	$tb -> ok (_reset_values($module), "reset values") or $tb -> diag ($@);  
 
191 
 
4
 
  
 50
   
 
 
 
 
 
 
 
955
 
 	$tb -> ok (_init_plugin($plugin),"init plugin"); $tb -> diag ($@) if $@;  
 
  
 
4
 
 
 
 
 
 
 
 
 
13
 
    
 
192 
 
4
 
  
 50
   
 
 
 
 
 
 
 
1112
 
 	$tb -> ok (_read($plugin),"read plugin") or $tb -> diag ($@);  
 
193 
 
4
 
 
 
 
 
 
 
 
 
12
 
 	my @values = _values ($module);  
 
194 
 
4
 
  
 50
   
 
 
 
 
 
 
 
935
 
 	$tb -> ok(@values, "read callback returned some values") or $tb -> diag ($@);  
 
195 
 
4
 
 
 
 
 
 
 
 
 
914
 
 	$tb -> ok(scalar @values, "dispatch called");  
 
196 
 
5
 
 
 
 
 
 
 
 
 
339
 
 	for (@values) {  
 
197 
 
5
 
 
 
 
 
 
 
 
 
1620
 
 		$tb->is_eq(ref $_,"ARRAY","value is array");  
 
198 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
199 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * There shall be only one and only one hashref argument  
 
200 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
201 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
202 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
203 
 
5
 
 
 
 
 
 
 
 
 
1125
 
 		$tb -> ok(scalar @$_, "plugin called dispatch with arguments");  
 
204 
 
5
 
 
 
 
 
 
 
 
 
1502
 
 		$tb -> cmp_ok (@$_, '>', 1, "only one value_list expected");  
 
205 
 
5
 
 
 
 
 
 
 
 
 
17
 
 		my $ref = ref $_->[0];  
 
206 
 
5
 
 
 
 
 
 
 
 
 
1573
 
 		$tb -> is_eq($ref, "HASH", "value is HASH"); # this should be handled already earlier  
 
207 
 
5
 
 
 
 
 
 
 
 
 
34
 
 		my %dispatch = %{$_->[0]};  
 
  
 
5
 
 
 
 
 
 
 
 
 
14
 
    
 
208 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
209 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * The following keys are mandatory: plugin, type, values  
 
210 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
211 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
212 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
213 
 
15
 
 
 
 
 
 
 
 
 
2258
 
 		for (qw(plugin type values)) {  
 
214 
 
5
 
  
 50
   
 
 
 
 
 
 
 
1133
 
 			$tb -> ok(exists $dispatch{$_}, "mandatory key '$_' exists") or return;  
 
215 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
216 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
217 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * Only the following keys are valid: plugin, type, values, time, interval, host, plugin_instance, type_instance.  
 
218 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
219 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
220 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
221 
 
35
 
 
 
 
 
 
 
 
 
9373
 
 		for (keys %dispatch) {  
 
222 
 
5
 
 
 
 
 
 
 
 
 
1475
 
 			$tb -> like ($_, qr/^(plugin|type|values|time|interval|host|plugin_instance|type_instance)$/, "key $_ is valid");  
 
223 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
224 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
225 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * The key C must be present in the C file.    
 
226 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
227 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
228 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
229 
 
5
 
 
 
 
 
 
 
 
 
37
 
 		my @type = _get_type($dispatch{type});  
 
230 
 
5
 
 
 
 
 
 
 
 
 
1293
 
 		$tb -> ok (scalar @type, "type $dispatch{type} found in " . join (", ", @$typesdb));  
 
231 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
232 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * The key C must be an array reference and the number of elements must match its data type in module's configuration option C.    
 
233 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
234 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
235 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
236 
 
5
 
 
 
 
 
 
 
 
 
16
 
 		my $vref = ref $dispatch{values};  
 
237 
 
5
 
 
 
 
 
 
 
 
 
1652
 
 		$tb -> is_eq ($vref, "ARRAY", "values is ARRAY");  
 
238 
 
5
 
 
 
 
 
 
 
 
 
28
 
 		$tb -> is_eq(scalar @{$dispatch{values}}, scalar @type, "number of dispatched 'values' matches type spec for '$dispatch{type}'");  
 
  
 
5
 
 
 
 
 
 
 
 
 
1616
 
    
 
239 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
240 
 
5
 
 
 
 
 
 
 
 
 
8
 
 		my $i=0;  
 
241 
 
5
 
 
 
 
 
 
 
 
 
13
 
 		for (@{$dispatch{values}}) {  
 
  
 
9
 
 
 
 
 
 
 
 
 
47
 
    
 
242 
 
9
 
 
 
 
 
 
 
 
 
2173
 
 			$tb -> ok (defined $_, "value $i for $dispatch{plugin} ($dispatch{type}) is defined");  
 
243 
 
5
 
 
 
 
 
 
 
 
 
13
 
 			$i++;  
 
244 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
245 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
246 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * All other keys must be scalar strings with at most 63 characters: C, C, C, C and C.       
 
247 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
248 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
249 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
250 
 
25
 
 
 
 
 
 
 
 
 
6236
 
 		for (qw(plugin type host plugin_instance type_instance)) {  
 
251 
 
25
 
  
 50
   
 
 
 
 
 
 
 
35
 
 			if (exists $dispatch{$_}) {  
 
252 
 
25
 
 
 
 
 
 
 
 
 
87
 
 				my $ref = ref $dispatch{$_};  
 
253 
 
25
 
 
 
 
 
 
 
 
 
8100
 
 				$tb -> is_eq ($ref, "", "$_ is SCALAR");  
 
254 
 
5
 
  
 50
   
 
 
 
 
 
 
 
1627
 
 				$tb -> cmp_ok(length $dispatch{$_}, '<', 63, "$_ is valid") if $dispatch{$_};  
 
255 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			}  
 
256 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
257 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
258 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * The keys C and C must be a positive integers.    
 
259 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
260 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
261 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
262 
 
10
 
 
 
 
 
 
 
 
 
30
 
 		for (qw(time interval)) {  
 
263 
 
5
 
  
100
   
 
 
 
 
 
 
 
23
 
 			if (exists $dispatch{$_}) {  
 
264 
 
5
 
 
 
 
 
 
 
 
 
1687
 
 				$tb -> cmp_ok($dispatch{$_},'>',0,"$_ is valid");  
 
265 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			}  
 
266 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
267 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
268 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * The keys C, C and C may use all ASCII characters except "/".     
 
269 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
270 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
271 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
272 
 
15
 
 
 
 
 
 
 
 
 
3332
 
 		for (qw/host plugin_instance type_instance/) {  
 
273 
 
15
 
  
 50
   
 
 
 
 
 
 
 
87
 
 			if (exists $dispatch{$_}) {  
 
274 
 
5
 
 
 
 
 
 
 
 
 
1658
 
 				$tb -> unlike($dispatch{$_}, qr/\//, "$_ valid");  
 
275 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			}  
 
276 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
277 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
278 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * The keys C and C may use all ASCII characters except "/" and "-".    
 
279 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
280 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
281 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
282 
 
10
 
 
 
 
 
 
 
 
 
1888
 
 		for (qw/plugin type/) {  
 
283 
 
10
 
  
 50
   
 
 
 
 
 
 
 
51
 
 			if (exists $dispatch{$_}) {  
 
284 
 
2
 
 
 
 
 
 
 
 
 
13
 
 				$tb -> unlike($dispatch{$_}, qr/[\/-]/, "$_ valid");  
 
285 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			}  
 
286 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
287 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
288 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
289 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
290 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
291 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
292 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
293 
 
4
 
 
 
 
 
 
 
 
 
1657
 
 }); # end subtest  
 
294 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
295 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
296 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 read_config_ok <$module> <$plugin> <$config> [$message]  
 
297 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
298 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Same as L but also reads configuration from $plugin_config and fires up the configuration callback of plugin $plugin_module. L will kindly format a configuration file or handle to suit this subroutine.    
 
299 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
300 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
301 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
302 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub read_config_ok ($$$;$) {  
 
303 
 
2
 
 
 
 
 
  
2
   
 
  
1
   
 
3
 
 	my $module = shift;  
 
304 
 
2
 
 
 
 
 
 
 
 
 
2
 
 	my $plugin = shift;  
 
305 
 
2
 
 
 
 
 
 
 
 
 
10
 
 	my $config = shift;  
 
306 
 
2
 
 
 
  
 50
   
 
 
 
 
 
15
 
 	my $msg = shift || "read with config OK";  
 
307 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
308 
 
2
 
 
 
 
 
 
 
 
 
28
 
 	my $tb = __PACKAGE__->builder;  
 
309 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	$tb -> subtest($msg, sub {  
 
310 
 
2
 
 
 
 
 
  
2
   
 
 
 
269
 
 			$tb -> plan ( tests => 3 );  
 
311 
 
2
 
 
 
 
 
 
 
 
 
655
 
 			$tb -> ok (_load_module($module), "load plugin module");  
 
312 
 
2
 
  
 50
   
 
 
 
 
 
 
 
623
 
 			$tb -> ok (_config($plugin,$config),"config ok") or $tb -> diag ($@);  
 
313 
 
18
 
 
 
 
 
 
 
 
 
10279
 
 			read_ok ($module,$plugin,$msg);  
 
314 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
315 
 
2
 
 
 
 
 
 
 
 
 
1041
 
 	);  
 
316 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
317 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
318 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
319 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 read_values (module, plugin, [ config ])  
 
320 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
321 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Returns arrayref containing the list of arguments passed to L. Example:   
 
322 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
323 
 
 
 
 
 
 
 
 
 
 
 
 
 
  [  
 
324 
 
 
 
 
 
 
 
 
 
 
 
 
 
   # first call to L   
 
325 
 
 
 
 
 
 
 
 
 
 
 
 
 
   [  
 
326 
 
 
 
 
 
 
 
 
 
 
 
 
 
    { plugin => "myplugin", type => "gauge", values => [ 1 ] },  
 
327 
 
 
 
 
 
 
 
 
 
 
 
 
 
   ],  
 
328 
 
 
 
 
 
 
 
 
 
 
 
 
 
   # second call to L   
 
329 
 
 
 
 
 
 
 
 
 
 
 
 
 
   [  
 
330 
 
 
 
 
 
 
 
 
 
 
 
 
 
    { plugin => "myplugin", type => "gauge", values => [ 2 ] },  
 
331 
 
 
 
 
 
 
 
 
 
 
 
 
 
   ],  
 
332 
 
 
 
 
 
 
 
 
 
 
 
 
 
  ]  
 
333 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
334 
 
 
 
 
 
 
 
 
 
 
 
 
 
 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 C's manpage (grep for "Config-Item").   
 
335 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Use L 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.   
 
336 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
337 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
338 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
339 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub read_values ($$;$) {  
 
340 
 
18
 
 
 
 
 
  
18
   
 
  
1
   
 
22
 
 	my $module = shift;  
 
341 
 
18
 
 
 
 
 
 
 
 
 
17
 
 	my $plugin = shift;  
 
342 
 
18
 
 
 
 
 
 
 
 
 
31
 
 	my $config = shift;  
 
343 
 
18
 
 
 
 
 
 
 
 
 
56
 
 	_load_module($module);  
 
344 
 
18
 
 
 
 
 
 
 
 
 
31
 
 	_init_plugin($plugin);  
 
345 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	# plugin with config callback  
 
346 
 
2
 
  
100
   
 
 
 
 
 
 
 
6
 
 	if ($config) {  
 
347 
 
18
 
 
 
 
 
 
 
 
 
28
 
 		_config($plugin,$config);  
 
348 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			#unless (ref $config eq "HASH") {  
 
349 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			#croak "third param to read_values must be a valid config hash";  
 
350 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			#}  
 
351 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			#my $cb = $FakeCollectd{$plugin}->{Callback}->{Config};  
 
352 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			#unless ($cb) {  
 
353 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			#croak "plugin $plugin does not provide a config callback";  
 
354 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			#}  
 
355 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			## this fires up the plugin's config callback with provided config  
 
356 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			#eval {no strict "refs"; &$cb($config)} or croak("config callback $cb failed: $@");  
 
357 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
358 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	#  
 
359 
 
18
 
 
 
 
 
 
 
 
 
79
 
 	my $reader = $FakeCollectd{$plugin}->{Callback}->{Read};  
 
360 
 
4
 
  
100
   
 
 
 
 
 
 
 
11
 
 	return unless $reader;  
 
361 
 
4
 
 
 
 
 
 
 
 
 
216
 
 	_reset_values($plugin);  
 
362 
 
4
 
 
 
 
 
 
 
 
 
59
 
 	eval "$reader()";  
 
363 
 
4
 
  
 50
   
 
 
 
 
 
 
 
12
 
 	return if $@;  
 
364 
 
4
 
  
 50
   
 
 
 
 
 
 
 
8
 
 	if (exists $FakeCollectd{$plugin}->{Values}) {  
 
365 
 
4
 
 
 
 
 
 
 
 
 
19
 
 		@{$FakeCollectd{$plugin}->{Values}};  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
    
 
366 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	} else {  
 
367 
 
5
 
 
 
 
 
 
 
 
 
8
 
 		return;  
 
368 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
369 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
370 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
371 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _get_type {  
 
372 
 
5
 
 
 
 
 
  
5
   
 
 
 
13
 
 	my $type = shift;  
 
373 
 
3
 
  
100
   
 
 
 
 
 
 
 
7
 
 	if ($typesdb) {  
 
374 
 
3
 
 
 
 
 
 
 
 
 
18
 
 		my $ref = ref $typesdb;  
 
375 
 
  
0
   
 
  
 50
   
 
 
 
 
 
 
 
0
 
 		if ($ref eq "HASH") {  
 
  
 
 
 
  
 50
   
 
 
 
 
 
 
 
 
 
    
 
376 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 			warn "typesdb is a hash, discarding its keys";  
 
377 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 			$typesdb = [values %$typesdb];  
 
378 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		} elsif ($ref eq "") {  
 
379 
 
2
 
 
 
 
 
 
 
 
 
13
 
 			$typesdb = [ $typesdb ];  
 
380 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
381 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	} else {  
 
382 
 
2
 
 
 
 
 
 
 
 
 
12
 
 		require File::ShareDir;  
 
383 
 
2
 
 
 
 
 
 
 
 
 
576
 
 		$typesdb = [ File::ShareDir::module_file(__PACKAGE__, "types.db") ];  
 
384 
 
5
 
 
 
 
 
 
 
 
 
15
 
 		 warn "no typesdb - using builtin ", join ", ", @$typesdb;  
 
385 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
386 
 
5
 
 
 
 
 
 
 
 
 
37
 
 	for my $file (@$typesdb) {  
 
387 
 
5
 
 
 
 
 
 
 
 
 
527
 
 		my $fh = IO::File -> new($file, "r");  
 
388 
 
  
0
   
 
  
 50
   
 
 
 
 
 
 
 
0
 
 		unless ($fh) {  
 
389 
 
  
0
   
 
 
 
 
 
 
 
 
 
0
 
 			cluck "Error opening types.db: $!";  
 
390 
 
5
 
 
 
 
 
 
 
 
 
86
 
 			return undef;  
 
391 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
392 
 
377
 
 
 
 
 
 
 
 
 
790
 
 		while (<$fh>) {  
 
393 
 
377
 
 
 
 
 
 
 
 
 
818
 
 			my ($t, @ds) = split /\s+/, $_;  
 
394 
 
5
 
  
100
   
 
 
 
 
 
 
 
5
 
 			if ($t eq $type) {  
 
395 
 
5
 
 
 
 
 
 
 
 
 
10
 
 				my @ret;  
 
396 
 
9
 
 
 
 
 
 
 
 
 
18
 
 				for (@ds) {  
 
397 
 
9
 
 
 
 
 
 
 
 
 
52
 
 					my @stuff = split /:/;  
 
398 
 
5
 
 
 
 
 
 
 
 
 
870
 
 					push @ret, {  
 
399 
 
 
 
 
 
 
 
 
 
 
 
 
 
 						ds   => $stuff[0],  
 
400 
 
 
 
 
 
 
 
 
 
 
 
 
 
 						type => $stuff[1],  
 
401 
 
 
 
 
 
 
 
 
 
 
 
 
 
 						min  => $stuff[2],  
 
402 
 
 
 
 
 
 
 
 
 
 
 
 
 
 						max  => $stuff[3],  
 
403 
 
 
 
 
 
 
 
 
 
 
 
 
 
 					};  
 
404 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				}  
 
405 
 
0
 
 
 
 
 
 
 
 
 
 
 
 				return @ret;  
 
406 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			}  
 
407 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		}  
 
408 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}  
 
409 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	return ();  
 
410 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
411 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
412 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 CAVEATS  
 
413 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
414 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 FakeCollectd  
 
415 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
416 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This module tricks the tested collectd plugins into loading L instead of L, 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.    
 
417 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
418 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 methods  
 
419 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
420 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Replacements for most common L 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.   
 
421 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
422 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 config  
 
423 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
424 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Although L has been a straight port of C (which itself is using C) to L/L, you might get different results in edge cases.       
 
425 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
426 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 types.db  
 
427 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
428 
 
 
 
 
 
 
 
 
 
 
 
 
 
 If no types.db list is being specified during construction, the object will try to use the shipped version.  
 
429 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Also, if a list is given, the first appearance of the type will be used; this may differ from collectd's mechanism.  
 
430 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
431 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 SEE ALSO  
 
432 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
433 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L, L    
 
434 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
435 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 AUTHOR  
 
436 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
437 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Fabien Wernli, C<<  >>   
 
438 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
439 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 BUGS  
 
440 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
441 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Please report any bugs or feature requests to L.   
 
442 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
443 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 SUPPORT  
 
444 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
445 
 
 
 
 
 
 
 
 
 
 
 
 
 
 You can find documentation for this module with the perldoc command.  
 
446 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
447 
 
 
 
 
 
 
 
 
 
 
 
 
 
     perldoc Test::Collectd::Plugins  
 
448 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
449 
 
 
 
 
 
 
 
 
 
 
 
 
 
 You can also look for information at:  
 
450 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
451 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
452 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
453 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * Github: https://github.com/faxm0dem/Test-Collectd-Plugins  
 
454 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
455 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * RT: CPAN's request tracker (report bugs here)  
 
456 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
457 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
458 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
459 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * AnnoCPAN: Annotated CPAN documentation  
 
460 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
461 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
462 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
463 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * CPAN Ratings  
 
464 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
465 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
466 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
467 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * Search CPAN  
 
468 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
469 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
470 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
471 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
472 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
473 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
474 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 LICENSE AND COPYRIGHT  
 
475 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
476 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Copyright 2012 Fabien Wernli.  
 
477 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
478 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This program is free software; you can redistribute it and/or modify it  
 
479 
 
 
 
 
 
 
 
 
 
 
 
 
 
 under the terms of either: the GNU General Public License as published  
 
480 
 
 
 
 
 
 
 
 
 
 
 
 
 
 by the Free Software Foundation; or the Artistic License.  
 
481 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
482 
 
 
 
 
 
 
 
 
 
 
 
 
 
 See http://dev.perl.org/licenses/ for more information.  
 
483 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
484 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
485 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
486 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
487 
 
 
 
 
 
 
 
 
 
 
 
 
 
 1; # End of Test::Collectd::Plugins  
 
488