1
2use Test::More tests => 20;
3use RRDTool::OO;
4use Log::Log4perl qw(:easy);
5
6$SIG{__WARN__} = sub {
7    use Carp qw(cluck);
8    print cluck();
9};
10
11##############################################
12# Configuration
13##############################################
14my $VIEW = 0;     # Display graphs
15my $VIEWPROG = "xv"; # using viewprog
16my $LOGLEVEL = $INFO;  # Level of detail
17##############################################
18
19sub view {
20    return unless $VIEW;
21    system($VIEWPROG, $_[0]) if ( -x $VIEWPROG );
22}
23
24#Log::Log4perl->easy_init({level => $LOGLEVEL, layout => "%m%n",
25##                          category => 'rrdtool',
26#file => 'stderr',
27#layout => '%F{1}-%L: %m%n',
28#});
29
30my $rrd = RRDTool::OO->new(file => "foo");
31
32######################################################################
33# Create a RRD "foo"
34######################################################################
35
36my $start_time     = 1080460200;
37my $nof_iterations = 40;
38my $end_time       = $start_time + $nof_iterations * 60;
39
40my $rc = $rrd->create(
41    start     => $start_time - 10,
42    step      => 60,
43    data_source => { name      => 'load1',
44                     type      => 'GAUGE',
45                     heartbeat => 90,
46                     min       => 0,
47                     max       => 10.0,
48                   },
49    data_source => { name      => 'load2',
50                     type      => 'GAUGE',
51                     heartbeat => 90,
52                     min       => 0,
53                     max       => 10.0,
54                   },
55    archive     => { cfunc    => 'MAX',
56                     xff      => '0.5',
57                     cpoints  => 1,
58                     rows     => 5,
59                   },
60    archive     => { cfunc    => 'MAX',
61                     xff      => '0.5',
62                     cpoints  => 5,
63                     rows     => 10,
64                   },
65    archive     => { cfunc    => 'MIN',
66                     xff      => '0.5',
67                     cpoints  => 1,
68                     rows     => 5,
69                   },
70    archive     => { cfunc    => 'MIN',
71                     xff      => '0.5',
72                     cpoints  => 5,
73                     rows     => 10,
74                   },
75);
76
77is($rc, 1, "create ok");
78ok(-f "foo", "RRD exists");
79
80for(0..$nof_iterations) {
81    my $time = $start_time + $_ * 60;
82    my $value = sprintf "%.2f", 2 + $_ * 0.1;
83
84    $rrd->update(time => $time, values => {
85        load1 => $value,
86        load2 => $value+1,
87    });
88}
89
90$rrd->fetch_start(start => $start_time, end => $end_time,
91                  cfunc => 'MAX');
92$rrd->fetch_skip_undef();
93while(my($time, $val1, $val2) = $rrd->fetch_next()) {
94    last unless defined $val1;
95    DEBUG "$time:$val1:$val2";
96}
97
98######################################################################
99# Create anoter RRD "bar"
100######################################################################
101
102my $rrd2 = RRDTool::OO->new(file => "bar");
103
104$start_time     = 1080460200;
105$nof_iterations = 40;
106$end_time       = $start_time + $nof_iterations * 60;
107
108$rc = $rrd2->create(
109    start     => $start_time - 10,
110    step      => 60,
111    data_source => { name      => 'load3',
112                     type      => 'GAUGE',
113                     heartbeat => 90,
114                     min       => 0,
115                     max       => 10.0,
116                   },
117    archive     => { cfunc    => 'AVERAGE',
118                     xff      => '0.5',
119                     cpoints  => 5,
120                     rows     => 10,
121                   },
122);
123
124is($rc, 1, "create ok");
125ok(-f "bar", "RRD exists");
126
127for(0..$nof_iterations) {
128    my $time = $start_time + $_ * 60;
129    my $value = sprintf "%.2f", 10 - $_ * 0.1;
130
131    $rrd2->update(time => $time, values => {
132        load3 => $value,
133    });
134}
135
136$rrd2->fetch_start(start => $start_time, end => $end_time,
137                   cfunc => 'AVERAGE');
138$rrd2->fetch_skip_undef();
139while(my($time, $val1) = $rrd2->fetch_next()) {
140    last unless defined $val1;
141    DEBUG "$time:$val1";
142}
143
144######################################################################
145# Draw simple graph
146######################################################################
147        # Simple line graph
148    $rrd->graph(
149      image          => "mygraph.png",
150      vertical_label => 'My Salary',
151      start          => $start_time,
152      end            => $start_time + $nof_iterations * 60,
153    );
154
155view("mygraph.png");
156ok(-f "mygraph.png", "Image exists");
157unlink "mygraph.png";
158
159######################################################################
160# Draw simple area graph
161######################################################################
162        # Simple line graph
163    $rrd->graph(
164      image          => "mygraph.png",
165      vertical_label => 'My Salary',
166      start          => $start_time,
167      end            => $start_time + $nof_iterations * 60,
168      draw           => {
169          type  => "area",
170          color => "00FF00",
171      },
172    );
173
174view("mygraph.png");
175ok(-f "mygraph.png", "Image exists");
176unlink "mygraph.png";
177
178######################################################################
179# Draw simple stacked graph
180######################################################################
181        # Simple stacked graph
182    $rrd->graph(
183      image          => "mygraph.png",
184      vertical_label => 'My Salary',
185      start          => $start_time,
186      end            => $start_time + $nof_iterations * 60,
187      draw           => {
188          type  => "area",
189          color => "00FF00",
190      },
191      draw           => {
192          dsname => "load2",
193          type   => "stack",
194          color  => "0000FF",
195      },
196    );
197
198view("mygraph.png");
199ok(-f "mygraph.png", "Image exists");
200unlink "mygraph.png";
201
202######################################################################
203# Draw a graph from two RRD files
204######################################################################
205$rrd->graph(
206  image          => "mygraph.png",
207  vertical_label => 'My Salary',
208  start          => $start_time,
209  end            => $start_time + $nof_iterations * 60,
210  width          => 700,
211  height         => 300,
212  draw           => {
213          type      => "line",
214          thickness => 3,
215          color     => '0000ff',
216          dsname    => 'load1',
217          cfunc     => 'MIN',
218  },
219  draw           => {
220          file      => 'bar',
221          type      => "line",
222          thickness => 3,
223          color     => 'ff0000',
224          # dsname    => 'load3',
225          # cfunc     => 'AVERAGE',
226  },
227);
228
229view("mygraph.png");
230ok(-f "mygraph.png", "Image exists");
231unlink "mygraph.png";
232
233######################################################################
234# Two draws in one graph, one DEF, one CDEF
235######################################################################
236    $rrd->graph(
237      image          => "mygraph.png",
238      vertical_label => 'draws and gprints',
239      start          => $start_time,
240      end            => $start_time + $nof_iterations * 60,
241      draw           => {
242          type      => "line",
243          thickness => 3,
244          color     => "00FF00",
245          name      => "first",
246          legend    => 'firstg',
247      },
248      gprint         => {
249        draw      => 'first',
250        cfunc     => 'AVERAGE',
251        format    => 'Average1=%lf',
252      },
253      draw          => {
254          type      => "line",
255          thickness => 3,
256          color     => "0000FF",
257          cdef      => "first,2,*",
258          name      => "second",
259          legend    => 'secondg',
260      },
261      gprint         => {
262        draw      => 'second',
263        cfunc     => 'AVERAGE',
264        format    => 'Average2=%lf',
265      },
266      draw          => {
267          type      => "line",
268          thickness => 3,
269          color     => "0000FF",
270          cdef      => "first,3,*",
271          name      => "third",
272          legend    => 'thirdg',
273      },
274      gprint         => {
275        draw      => 'third',
276        cfunc     => 'AVERAGE',
277        format    => 'Average3=%lf',
278      },
279      draw          => {
280          type      => "line",
281          thickness => 3,
282          color     => "0000FF",
283          cdef      => "first,4,*",
284      },
285    );
286
287view("mygraph.png");
288ok(-f "mygraph.png", "Image exists");
289unlink "mygraph.png";
290
291######################################################################
292# Test
293######################################################################
294    $rrd->graph(
295      image          => "mygraph.png",
296      vertical_label => 'My Salary',
297      start          => $start_time,
298      end            => $start_time + $nof_iterations * 60,
299      draw           => {
300        type      => 'line',
301        color     => 'FF0000', # red line
302        name      => 'firstgraph',
303        legend    => 'Unmodified Load',
304      },
305      draw        => {
306        type      => 'line',
307        color     => '00FF00', # green line
308        cdef      => "firstgraph,2,*",
309        legend    => 'Load Doubled Up',
310      },
311    );
312
313view("mygraph.png");
314ok(-f "mygraph.png", "Image exists");
315unlink "mygraph.png";
316
317######################################################################
318# Test
319######################################################################
320    $rrd->graph(
321      image          => "mygraph.png",
322      vertical_label => 'My Salary',
323      start          => $start_time,
324      end            => $start_time + $nof_iterations * 60,
325      draw           => {
326        type      => 'hidden',
327        color     => 'FF0000', # red line
328        name      => 'firstgraph',
329        legend    => 'Unmodified Load',
330      },
331      draw        => {
332        type      => 'line',
333        color     => '00FF00', # green line
334        cdef      => "firstgraph,2,*",
335        legend    => 'Load Doubled Up',
336      },
337    );
338
339view("mygraph.png");
340ok(-f "mygraph.png", "Image exists");
341unlink "mygraph.png";
342
343######################################################################
344# Test gprint
345######################################################################
346    $rrd->graph(
347      image          => "mygraph.png",
348      vertical_label => 'Test gprint',
349      start          => $start_time,
350      end            => $start_time + $nof_iterations * 60,
351      draw           => {
352        type      => 'line',
353        color     => 'FF0000', # red line
354        name      => 'firstgraph',
355        legend    => 'Unmodified Load',
356      },
357      draw           => {
358        type      => 'hidden',
359        name      => 'average_of_first_draw',
360        vdef      => 'firstgraph,AVERAGE',
361      },
362      gprint         => {
363        draw   => 'average_of_first_draw',
364        format => "Hello %lf",
365      },
366    );
367
368view("mygraph.png");
369ok(-f "mygraph.png", "Image exists");
370unlink "mygraph.png";
371
372######################################################################
373# Test comment, vrule
374######################################################################
375    $rrd->graph(
376      image          => "mygraph.png",
377      vertical_label => 'Test comment, vrule',
378      start          => $start_time,
379      end            => $start_time + $nof_iterations * 60,
380      draw           => {
381        type      => 'line',
382        color     => 'FF0000', # red line
383        name      => 'firstgraph',
384        legend    => 'Unmodified Load',
385      },
386      gprint         => {
387        draw      => 'firstgraph',
388        cfunc     => 'AVERAGE',
389        format    => 'Average=%lf',
390      },
391      comment     => "Remember, 83% of all statistics are made up",
392      vrule       => {
393                time   => $start_time + 10 * 60,
394                legend => "vrule1",
395                color  => "#ff0000",
396      },
397      vrule       => {
398                time   => $start_time + 20 * 60,
399                legend => "vrule2",
400                color  => "#00ff00",
401      },
402      hrule       => {
403                value   => 2.5,
404                legend => "hrule1",
405                color  => "#0000ff",
406      },
407      hrule       => {
408                value   => 3.5,
409                legend => "hrule2",
410                color  => "#aa00aa",
411      },
412#      font => { name    => "/usr/X11R6/lib/X11/fonts/TTF/VeraBd.ttf",
413#                size    => 32,
414#                element => "title",
415#              },
416    );
417
418view("mygraph.png");
419ok(-f "mygraph.png", "Image exists");
420unlink "mygraph.png";
421
422######################################################################
423# Test line, area
424######################################################################
425    $rrd->graph(
426      image          => "mygraph.png",
427      vertical_label => 'Test line, area',
428      width          => 1000,
429      start          => $start_time,
430      end            => $start_time + $nof_iterations * 60,
431      draw           => {
432        type      => 'line',
433        color     => 'FF0000', # red line
434        name      => 'firstgraph',
435        legend    => 'Unmodified Load',
436      },
437      line        => {
438                value  => 3,
439                legend => "line1",
440                color  => "#00ff00",
441                stack  => 1,
442      },
443      line        => {
444                value  => 10,
445                legend => "line2",
446                color  => "#ff0000",
447      },
448      area        => {
449                value  => 5,
450                legend => "area1",
451                color  => "#0000ff",
452      },
453      tick        => {
454                legend => "ticks",
455                color  => "#00ff00",
456                fraction => 0.5,
457      },
458      shift       => {
459                draw  => 'firstgraph',
460                offset => 1000,
461      },
462    );
463
464view("mygraph.png");
465ok(-f "mygraph.png", "Image exists");
466unlink "mygraph.png";
467
468######################################################################
469# Test stack compatibility
470######################################################################
471    $rrd->graph(
472      image          => "mygraph.png",
473      vertical_label => 'Stack',
474      width          => 1000,
475      start          => $start_time,
476      end            => $start_time + $nof_iterations * 60,
477      draw           => {
478        type      => 'stack',
479        color     => 'FF0000', # red area
480        name      => 'firstgraph',
481        legend    => 'first',
482      },
483      draw           => {
484        type      => 'stack',
485        color     => '00FF00', # green area
486        name      => 'secondgraph',
487        legend    => 'second',
488      },
489    );
490
491view("mygraph.png");
492ok(-f "mygraph.png", "Image exists");
493unlink "mygraph.png";
494
495######################################################################
496# Test stacks
497######################################################################
498    $rrd->graph(
499      image          => "mygraph.png",
500      vertical_label => 'Stack',
501      width          => 1000,
502      start          => $start_time,
503      end            => $start_time + $nof_iterations * 60,
504      draw           => {
505        type      => 'area',
506        color     => 'FF0000', # red area
507        name      => 'firstgraph',
508        legend    => 'first',
509        stack     => 1,
510      },
511      draw           => {
512        type      => 'line',
513        color     => '00FF00', # green line
514        name      => 'secondgraph',
515        legend    => 'second',
516        stack     => 1,
517      },
518    );
519
520view("mygraph.png");
521ok(-f "mygraph.png", "Image exists");
522unlink "mygraph.png";
523
524VDEF:
525######################################################################
526# Test vdef, gprint
527######################################################################
528    $rrd->graph(
529      image          => "mygraph.png",
530      vertical_label => 'Test vdef, gprint',
531      width          => 1000,
532      start          => $start_time,
533      end            => $start_time + $nof_iterations * 60,
534      draw           => {
535        type      => 'line',
536        name      => 'firstdraw',
537        legend    => 'Unmodified Load',
538      },
539      draw           => {
540        type      => 'hidden',
541        name      => 'average_of_firstgraph',
542        vdef      => 'firstdraw,AVERAGE',
543      },
544      gprint         => {
545        draw      => 'average_of_firstgraph',
546        format    => 'Average=%lf',
547      },
548    );
549
550view("mygraph.png");
551ok(-f "mygraph.png", "Image exists");
552unlink "mygraph.png";
553
554PRINT:
555######################################################################
556# Test print
557######################################################################
558    $rrd->graph(
559      image          => "mygraph.png",
560      vertical_label => 'Test vdef, gprint',
561      width          => 1000,
562      start          => $start_time,
563      end            => $start_time + $nof_iterations * 60,
564      draw           => {
565        type      => 'line',
566        name      => 'firstdraw',
567        legend    => 'Unmodified Load',
568      },
569      draw           => {
570        type      => 'hidden',
571        name      => 'average_of_firstgraph',
572        vdef      => 'firstdraw,AVERAGE',
573      },
574      print         => {
575        draw      => 'average_of_firstgraph',
576        format    => "\"Average=%lf\"",
577      },
578    );
579
580		my @prgraph = (
581      image          => "mygraph.png",
582      start          => $start_time,
583      end            => $start_time + $nof_iterations * 60,
584      draw           => {
585          type      => "hidden",
586          name      => "firstdraw",
587          #cfunc     => 'AVERAGE'
588      },
589      draw           => {
590          type      => "hidden",
591          color     => '00FF00', # green line
592          name      => "in95precent",
593          vdef      => "firstdraw,95,PERCENT"
594      },
595
596      print         => {
597          draw      => 'in95precent',
598          format    => "Result = %3.2lf",
599        },
600		);
601    $rrd->graph(
602			@prgraph,
603    );
604
605
606SKIP: {
607    skip "Skipping potentially buggy RRDs < 1.4 for print/format", 1 if
608        $RRDs::VERSION < 1.4;
609    is($rrd->print_results()->[0], "Result = 6.00", "print result");
610}
611
612######################################################################
613# Draw simple graphv
614######################################################################
615SKIP: {
616    eval "use RRDs 1.3";
617    skip "RRDs is too old: need 1.3 for graphv", 2 if $@;
618
619        # Simple line graph
620    $rrd->graphv( @prgraph );
621
622    ok(-f "mygraph.png", "Image exists");
623    unlink "mygraph.png";
624    skip "Skipping potentially buggy RRDs < 1.4 for print/format", 1 if
625       $RRDs::VERSION < 1.4;
626    is($rrd->print_results()->{'print[0]'}, "Result = 6.00", "print result");
627}
628
629unlink("foo");
630unlink("bar");
631