1#!/usr/bin/perl
2
3use strict;
4use warnings;
5use lib 't/lib';
6
7use English qw(-no_match_vars);
8use IO::Capture::Stderr;
9use File::stat;
10use File::Temp qw(tempdir);
11use Fcntl qw(:seek);
12use Test::More;
13use Test::NoWarnings;
14
15use FusionInventory::Agent::Config;
16use FusionInventory::Agent::Logger;
17
18plan tests => 29;
19
20my $logger = FusionInventory::Agent::Logger->new();
21
22isa_ok(
23    $logger,
24    'FusionInventory::Agent::Logger',
25    'logger class'
26);
27
28is(
29    @{$logger->{backends}},
30    1,
31    'one default backend'
32);
33
34isa_ok(
35    $logger->{backends}->[0],
36    'FusionInventory::Agent::Logger::Stderr',
37    'default backend class'
38);
39
40if ($OSNAME eq 'MSWin32') {
41
42    $logger = FusionInventory::Agent::Logger->new(
43        config => FusionInventory::Agent::Config->new(
44            options => {
45                config  => 'none',
46                logger  => 'stderr,Test'
47            }
48        )
49    );
50    is(
51        @{$logger->{backends}},
52        2,
53        'three backends'
54    );
55
56    subtest 'backends classes' => sub {
57        plan tests => 2;
58        isa_ok(
59            $logger->{backends}->[0],
60            'FusionInventory::Agent::Logger::Stderr',
61            'first backend class'
62        );
63
64        isa_ok(
65            $logger->{backends}->[1],
66            'FusionInventory::Agent::Logger::Test',
67            'third backend class'
68        );
69    };
70} else {
71    $logger = FusionInventory::Agent::Logger->new(
72        config => FusionInventory::Agent::Config->new(
73            options => {
74                config  => 'none',
75                logger  => 'Stderr,Syslog,Test'
76            }
77        )
78    );
79
80    is(
81        @{$logger->{backends}},
82        3,
83        'three backends'
84    );
85
86    subtest 'backends classes' => sub {
87        plan tests => 3;
88        isa_ok(
89            $logger->{backends}->[0],
90            'FusionInventory::Agent::Logger::Stderr',
91            'first backend class'
92        );
93
94        isa_ok(
95            $logger->{backends}->[1],
96            'FusionInventory::Agent::Logger::Syslog',
97            'second backend class'
98        );
99
100        isa_ok(
101            $logger->{backends}->[2],
102            'FusionInventory::Agent::Logger::Test',
103            'third backend class'
104        );
105    };
106}
107
108# stderr backend tests
109
110$logger = FusionInventory::Agent::Logger->new(
111    config => FusionInventory::Agent::Config->new(
112        options => {
113            config  => 'none',
114            logger  => 'stderr'
115        }
116    )
117);
118
119ok(
120    !getStderrOutput(sub { $logger->debug2('message'); }),
121    'debug2 message absence'
122);
123
124ok(
125    !getStderrOutput(sub { $logger->debug('message'); }),
126    'debug message absence'
127);
128
129# Test just updating debug level
130$logger = FusionInventory::Agent::Logger->new(
131    debug => 1
132);
133
134ok(
135    !getStderrOutput(sub { $logger->debug2('message'); }),
136    'debug2 message absence'
137);
138
139ok(
140    getStderrOutput(sub { $logger->debug('message'); }),
141    'debug message presence'
142);
143
144is(
145    getStderrOutput(sub { $logger->debug('message'); }),
146    "[debug] message",
147    'debug message formating'
148);
149
150is(
151    getStderrOutput(sub { $logger->info('message'); }),
152    "[info] message",
153    'info message formating'
154);
155
156is(
157    getStderrOutput(sub { $logger->warning('message'); }),
158    "[warning] message",
159    'warning message formating'
160);
161
162is(
163    getStderrOutput(sub { $logger->error('message'); }),
164    "[error] message",
165    'error message formating'
166);
167
168$logger = FusionInventory::Agent::Logger->new(
169    config => FusionInventory::Agent::Config->new(
170        options => {
171            config  => 'none',
172            debug   => 2,
173            logger  => 'stderr'
174        }
175    )
176);
177
178ok(
179    getStderrOutput(sub { $logger->debug2('message'); }),
180    'debug2 message presence'
181);
182
183ok(
184    getStderrOutput(sub { $logger->debug('message'); }),
185    'debug message presence'
186);
187
188$logger = FusionInventory::Agent::Logger->new(
189    config => FusionInventory::Agent::Config->new(
190        options => {
191            config  => 'none',
192            debug   => 1,
193            color   => 1,
194            logger  => 'stderr'
195        }
196    )
197);
198
199is(
200    getStderrOutput(sub { $logger->debug('message'); }),
201    "\033[1;1m[debug]\033[0m message",
202    'debug message color formating'
203);
204
205is(
206    getStderrOutput(sub { $logger->info('message'); }),
207    "\033[1;34m[info]\033[0m message",
208    'info message color formating'
209);
210
211is(
212    getStderrOutput(sub { $logger->warning('message'); }),
213    "\033[1;35m[warning] message\033[0m",
214    'warning message color formating'
215);
216
217is(
218    getStderrOutput(sub { $logger->error('message'); }),
219    "\033[1;31m[error] message\033[0m",
220    'error message color formating'
221);
222
223# Test just updating color config
224$logger = FusionInventory::Agent::Logger->new(
225    color => 0
226);
227
228is(
229    getStderrOutput(sub { $logger->error('message'); }),
230    "[error] message",
231    'error message after color formating removed'
232);
233
234# file backend tests
235my $tmpdir = tempdir(CLEANUP => $ENV{TEST_DEBUG} ? 0 : 1);
236my $logfile;
237
238$logfile = "$tmpdir/test1";
239$logger = FusionInventory::Agent::Logger->new(
240    config => FusionInventory::Agent::Config->new(
241        options => {
242            config  => 'none',
243            logger  => 'file',
244            logfile => $logfile
245        }
246    )
247);
248
249$logger->debug('message');
250
251ok(
252    !-f $logfile,
253    'debug message absence'
254);
255
256$logfile = "$tmpdir/test2";
257$logger = FusionInventory::Agent::Logger->new(
258    config => FusionInventory::Agent::Config->new(
259        options => {
260            config  => 'none',
261            debug   => 1,
262            logger  => 'file',
263            logfile => $logfile
264        }
265    )
266);
267$logger->debug('message');
268
269ok(
270    -f $logfile,
271    'debug message presence'
272);
273
274is(
275    getFileOutput($logfile, sub { $logger->debug('message'); }),
276    '[' . localtime() . '][debug] message',
277    'debug message formating'
278);
279
280is(
281    getFileOutput($logfile, sub { $logger->info('message'); }),
282    '[' . localtime() . '][info] message',
283    'info message formating'
284);
285
286is(
287    getFileOutput($logfile, sub { $logger->warning('message'); }),
288    '[' . localtime() . '][warning] message',
289    'warning message formating'
290);
291
292is(
293    getFileOutput($logfile, sub { $logger->error('message'); }),
294    '[' . localtime() . '][error] message',
295    'error message formating'
296);
297
298$logfile = "$tmpdir/test3";
299$logger = FusionInventory::Agent::Logger->new(
300    config => FusionInventory::Agent::Config->new(
301        options => {
302            config  => 'none',
303            logger  => 'file',
304            logfile => $logfile
305        }
306    )
307);
308fillLogFile($logger);
309ok(
310    getFileSize($logfile) > 1024 * 1024,
311    'no size limitation'
312);
313
314$logfile = "$tmpdir/test4";
315$logger = FusionInventory::Agent::Logger->new(
316    config => FusionInventory::Agent::Config->new(
317        options => {
318            config  => 'none',
319            logger  => 'file',
320            logfile => $logfile,
321            'logfile-maxsize' => 1
322        }
323    )
324);
325fillLogFile($logger);
326ok(
327    getFileSize($logfile) < 1024 * 1024,
328    'size limitation'
329);
330
331sub getStderrOutput {
332    my ($callback) = @_;
333
334    my $capture = IO::Capture::Stderr->new();
335
336    $capture->start();
337    $callback->();
338    $capture->stop();
339
340    my $line = $capture->read();
341    chomp $line if $line;
342
343    return $line;
344}
345
346sub getFileOutput {
347    my ($file, $callback) = @_;
348
349    my $stat = stat $file;
350
351    $callback->();
352
353    open (my $fh, '<', $file) or die "can't open $file: $ERRNO";
354    seek $fh, $stat->size(), SEEK_SET;
355    my $line = <$fh>;
356    close $fh;
357
358    chomp $line;
359    return $line;
360}
361
362sub fillLogFile {
363    my ($logger) = @_;
364    foreach my $i (0 .. 1023) {
365        $logger->info(chr(65 + $i % 26) x 1024);
366    }
367}
368
369sub getFileSize {
370    my ($file) = @_;
371    my $stat = stat $file;
372    return $stat->size();
373}
374