1
2use Test::More qw(no_plan);
3use RRDTool::OO;
4use POSIX qw(setlocale LC_ALL);
5use FindBin qw( $Bin );
6
7require "$Bin/inc/round.t";
8
9use Log::Log4perl qw(:easy);
10#Log::Log4perl->easy_init({level => $INFO, layout => "%L: %m%n",
11#                          category => 'rrdtool',
12#                          file => 'stdout'});
13
14my $rrd;
15my $loc = setlocale( LC_ALL, "C" );
16
17######################################################################
18    # constructor missing mandatory parameter
19eval { $rrd = RRDTool::OO->new(); };
20like($@, qr/Mandatory parameter 'file' not set/, "new without file");
21
22    # constructor featuring illegal parameter
23eval { $rrd = RRDTool::OO->new( file => 'file', foobar => 'abc' ); };
24like($@, qr/Illegal parameter 'foobar' in new/, "new with illegal parameter");
25
26    # Legal constructor
27$rrd = RRDTool::OO->new( file => 'foo' );
28
29######################################################################
30# create missing everything
31######################################################################
32eval { $rrd->create(); };
33like($@, qr/Mandatory parameter/, "create missing everything");
34
35    # create missing data_source
36eval { $rrd->create( archive => {} ); };
37like($@, qr/Mandatory parameter/, "create missing data_source");
38
39    # create missing archive
40eval { $rrd->create( data_source => {} ); };
41like($@, qr/No archives/, "create missing archive");
42
43    # create with superfluous param
44eval { $rrd->create(
45    data_source => { name      => 'foobar',
46                     type      => 'foo',
47                     # heartbeat => 10,
48                   },
49    archive     => { cfunc   => 'abc',
50                     name    => 'archname',
51                     xff     => '0.5',
52                     cpoints => 5,
53                     rows    => 10,
54                   },
55) };
56
57like($@, qr/Illegal parameter 'name'/, "create missing heartbeat");
58
59######################################################################
60# Run the test example in
61# http://www.linux-magazin.de/Artikel/ausgabe/2004/06/perl/perl.html
62######################################################################
63
64my $start_time     = 1080460200;
65my $nof_iterations = 40;
66my $end_time       = $start_time + $nof_iterations * 60;
67
68my $rc = $rrd->create(
69    start     => $start_time - 10,
70    step      => 60,
71    data_source => { name      => 'load',
72                     type      => 'GAUGE',
73                     heartbeat => 90,
74                     min       => 0,
75                     max       => 10.0,
76                   },
77    archive     => { cfunc    => 'MAX',
78                     xff      => '0.5',
79                     cpoints  => 1,
80                     rows     => 5,
81                   },
82    archive     => { cfunc    => 'MAX',
83                     xff      => '0.5',
84                     cpoints  => 5,
85                     rows     => 10,
86                   },
87);
88
89is($rc, 1, "create ok");
90ok(-f "foo", "RRD exists");
91
92for(0..$nof_iterations) {
93    my $time = $start_time + $_ * 60;
94    my $value = sprintf "%.2f", 2 + $_ * 0.1;
95
96    $rrd->update(time => $time, value => $value);
97}
98
99    # short-term archive
100my @expected = qw(1080462360:5.6 1080462420:5.7 1080462480:5.8
101                  1080462540:5.9 1080462600:6);
102
103$rrd->fetch_start(start => $end_time - 5*60, end => $end_time,
104                  cfunc => 'MAX');
105$rrd->fetch_skip_undef();
106my $count = 0;
107while(my($time, $val) = $rrd->fetch_next()) {
108    last unless defined $val;
109      # rrdtool has some inaccurracies [rt.cpan.org #97322]
110    $val = roundfloat( $val );
111    is("$time:$val", shift @expected, "match expected value");
112    $count++;
113}
114is($count, 5, "items found");
115
116    # long-term archive
117@expected = qw(1080461100:3.5 1080461400:4 1080461700:4.5 1080462000:5 1080462300:5.5 1080462600:6);
118
119$rrd->fetch_start(start => $end_time - 30*60, end => $end_time,
120                  cfunc => 'MAX');
121$rrd->fetch_skip_undef();
122$count = 0;
123while(my($time, $val) = $rrd->fetch_next()) {
124    last unless defined $val;
125        # older rrdtool installations show an additional value
126    next if "$time:$val" eq "1080460800:3";
127    is("$time:$val", shift @expected, "match expected value");
128    $count++;
129}
130is($count, 6, "items found");
131
132######################################################################
133# check info for this rrd
134######################################################################
135my $info = $rrd->info;
136is $info->{'ds'}{'load'}{'type'} => 'GAUGE', 'check RRDTool::OO::info';
137is $info->{'ds'}{'load'}{'max'} => '10', 'check RRDTool::OO::info';
138is $info->{'rra'}['1']{'cf'} => 'MAX', 'check RRDTool::OO::info';
139
140######################################################################
141# Failed update: time went backwards
142######################################################################
143$rrd->{raise_error} = 0;
144ok(! $rrd->update(value => 123, time => 123),
145   "update with expired timestamp");
146$rrd->{raise_error} = 1;
147
148like($rrd->error_message(), qr/illegal attempt to update using time \d+ when last update time is \d+ \(minimum one second step\)/, "check error message");
149
150######################################################################
151# Ok update
152######################################################################
153ok($rrd->update(value => 123, time => 1080500000),
154   "update with ok timestamp");
155
156######################################################################
157# Check what happens if the rrd is write-protected all of a sudden
158######################################################################
159SKIP: {
160    chmod 0444, "foo";
161    skip "can't make test file unwritable (are you root?)", 1 if -w "foo";
162
163    eval {
164        $rrd->update(value => 123, time => 1080500100);
165    };
166
167    if($@) {
168        ok($@, "update on write-protected rrd");
169    } else {
170        fail("update on write-protected rrd");
171    }
172}
173
174######################################################################
175    # constructor including raise_error (cpan #7897)
176$rrd = RRDTool::OO->new(file => "foo1", raise_error => 0);
177eval { $rrd->update(value => 123, time => 123); };
178is($@, "", "Error caught");
179
180$rrd = RRDTool::OO->new(file => "foo1", raise_error => 1);
181eval { $rrd->update(value => 123, time => 123); };
182like($@, qr/No such file or directory/, "Error raised");
183
184END { unlink('foo'); }
185