root/honeyclient/branches/exp/jpuchalski-active_content/t/honeyclient_agent_integrity_filesystem.t

Revision 628, 11.6 kB (checked in by kindlund, 1 year ago)

Partial merge of trunk into active_content branch.

Line 
1 #!/usr/bin/perl -w
2
3 use strict;
4 use Test::More 'no_plan';
5 $| = 1;
6
7
8
9 # =begin testing
10 {
11 # Make sure Log::Log4perl loads
12 BEGIN { use_ok('Log::Log4perl', qw(:nowarn))
13         or diag("Can't load Log::Log4perl package. Check to make sure the package library is correctly listed within the path.");
14
15         # Suppress all logging messages, since we need clean output for unit testing.
16         Log::Log4perl->init({
17             "log4perl.rootLogger"                               => "DEBUG, Buffer",
18             "log4perl.appender.Buffer"                          => "Log::Log4perl::Appender::TestBuffer",
19             "log4perl.appender.Buffer.min_level"                => "fatal",
20             "log4perl.appender.Buffer.layout"                   => "Log::Log4perl::Layout::PatternLayout",
21             "log4perl.appender.Buffer.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n",
22         });
23 }
24 require_ok('Log::Log4perl');
25 use Log::Log4perl qw(:easy);
26
27 # Make sure the module loads properly, with the exportable
28 # functions shared.
29 BEGIN { use_ok('HoneyClient::Util::Config', qw(getVar setVar))
30         or diag("Can't load HoneyClient::Util::Config package.  Check to make sure the package library is correctly listed within the path."); }
31 require_ok('HoneyClient::Util::Config');
32 can_ok('HoneyClient::Util::Config', 'getVar');
33 can_ok('HoneyClient::Util::Config', 'setVar');
34 use HoneyClient::Util::Config qw(getVar setVar);
35
36 # Suppress all logging messages, since we need clean output for unit testing.
37 Log::Log4perl->init({
38     "log4perl.rootLogger"                               => "DEBUG, Buffer",
39     "log4perl.appender.Buffer"                          => "Log::Log4perl::Appender::TestBuffer",
40     "log4perl.appender.Buffer.min_level"                => "fatal",
41     "log4perl.appender.Buffer.layout"                   => "Log::Log4perl::Layout::PatternLayout",
42     "log4perl.appender.Buffer.layout.ConversionPattern" => "%d{yyyy-MM-dd HH:mm:ss} %5p [%M] (%F:%L) - %m%n",
43 });
44
45 # Make sure Data::Dumper loads
46 BEGIN { use_ok('Data::Dumper')
47         or diag("Can't load Data::Dumper package. Check to make sure the package library is correctly listed within the path."); }
48 require_ok('Data::Dumper');
49 use Data::Dumper;
50
51 # Make sure Storable loads
52 BEGIN { use_ok('Storable', qw(nfreeze thaw dclone))
53         or diag("Can't load Storable package. Check to make sure the package library is correctly listed within the path."); }
54 require_ok('Storable');
55 can_ok('Storable', 'nfreeze');
56 can_ok('Storable', 'thaw');
57 can_ok('Storable', 'dclone');
58 use Storable qw(nfreeze thaw dclone);
59
60 # Make sure File::Find loads.
61 BEGIN { use_ok('File::Find', qw(find)) or diag("Can't load File::Find package.  Check to make sure the package library is correctly listed within the path."); }
62 require_ok('File::Find');
63 can_ok('File::Find', 'find');
64 use File::Find;
65
66 # Make sure Filesys::CygwinPaths loads
67 BEGIN { use_ok('Filesys::CygwinPaths')
68         or diag("Can't load Filesys::CygwinPaths package. Check to make sure the package library is correctly listed within the path."); }
69 require_ok('Filesys::CygwinPaths');
70 use Filesys::CygwinPaths qw(:all);
71
72 # Make sure Algorithm::Diff loads.
73 BEGIN { use_ok('Algorithm::Diff') or diag("Can't load Algorithm::Diff package.  Check to make sure the package library is correctly listed within the path."); }
74 require_ok('Algorithm::Diff');
75 use Algorithm::Diff;
76
77 # Make sure File::Basename loads.
78 BEGIN { use_ok('File::Basename', qw(dirname)) or diag("Can't load File::Basename package.  Check to make sure the package library is correctly listed within the path."); }
79 require_ok('File::Basename');
80 can_ok('File::Basename', 'dirname');
81 use File::Basename qw(dirname);
82
83 # Make sure HoneyClient::Agent::Integrity::Filesystem loads.
84 BEGIN { use_ok('HoneyClient::Agent::Integrity::Filesystem') or diag("Can't load HoneyClient::Agent::Integrity::Filesystem package.  Check to make sure the package library is correctly listed within the path."); }
85 require_ok('HoneyClient::Agent::Integrity::Filesystem');
86 use HoneyClient::Agent::Integrity::Filesystem;
87
88 # Make sure DateTime loads.
89 BEGIN { use_ok('DateTime') or diag("Can't load DateTime package.  Check to make sure the package library is correctly listed within the path."); }
90 require_ok('DateTime');
91 use DateTime;
92
93 # Make sure Digest::MD5 loads.
94 BEGIN { use_ok('Digest::MD5') or diag("Can't load Digest::MD5 package.  Check to make sure the package library is correctly listed within the path."); }
95 require_ok('Digest::MD5');
96 use Digest::MD5;
97
98 # Make sure Digest::SHA loads.
99 BEGIN { use_ok('Digest::SHA') or diag("Can't load Digest::SHA package.  Check to make sure the package library is correctly listed within the path."); }
100 require_ok('Digest::SHA');
101 use Digest::SHA;
102
103 # Make sure File::Type loads.
104 BEGIN { use_ok('File::Type') or diag("Can't load File::Type package.  Check to make sure the package library is correctly listed within the path."); }
105 require_ok('File::Type');
106 use File::Type;
107
108 # Make sure IO::File loads.
109 BEGIN { use_ok('IO::File') or diag("Can't load IO::File package.  Check to make sure the package library is correctly listed within the path."); }
110 require_ok('IO::File');
111 use IO::File;
112 }
113
114
115
116 # =begin testing
117 {
118 diag("These tests will create temporary files in /tmp.  Be sure to cleanup this directory, if any of these tests fail.");
119
120 # Create a generic Filesystem object, with test state data.
121 my $filesystem = HoneyClient::Agent::Integrity::Filesystem->new(test => 1, bypass_baseline => 1);
122 is($filesystem->{test}, 1, "new(test => 1, bypass_baseline => 1)") or diag("The new() call failed.");
123 isa_ok($filesystem, 'HoneyClient::Agent::Integrity::Filesystem', "new(test => 1, bypass_baseline => 1)") or diag("The new() call failed.");
124
125 diag("Performing baseline check of the filesystem; this may take some time...");
126
127 # Perform baseline.
128 $filesystem = HoneyClient::Agent::Integrity::Filesystem->new();
129 isa_ok($filesystem, 'HoneyClient::Agent::Integrity::Filesystem', "new()") or diag("The new() call failed.");
130 }
131
132
133
134 # =begin testing
135 {
136 ### Get the test directory to monitor.
137 my $monitor_dir = $ENV{PWD} . "/" . getVar(name      => "monitor_dir",
138                                            namespace => "HoneyClient::Agent::Integrity::Filesystem::Test");
139
140 ### Seed the directory with test data.
141 my $delete_file = $monitor_dir . "/" . "to_delete.txt";
142 my $change_file = $monitor_dir . "/" . "to_change.txt";
143 my $add_file    = $monitor_dir . "/" . "to_add.txt";
144
145 my $delete_string  = "Test string for the file to be deleted.";
146 my $add_string     = "Test string for the added file.";
147 my $change_string1 = "Original test string for the file to be changed.";
148 my $change_string2 = "Final test string for the changed file.";
149
150 my @file_attr;
151
152 open(DELETE_FILE, ">", $delete_file) or BAIL_OUT("Unable to create test file '" . $delete_file . "'.");
153 print DELETE_FILE $delete_string;
154 close DELETE_FILE;
155
156 @file_attr = stat($delete_file);
157 my $delete_file_size  = $file_attr[7];
158 my $delete_file_mtime = $file_attr[9];
159
160 open(CHANGE_FILE, ">", $change_file) or BAIL_OUT("Unable to create test file '" . $change_file . "'.");
161 print CHANGE_FILE $change_string1;
162 close CHANGE_FILE;
163
164 @file_attr = stat($change_file);
165 my $change_file_size1  = $file_attr[7];
166 my $change_file_mtime1 = $file_attr[9];
167
168 # Make sure the $add_file isn't present.
169 unlink($add_file);
170
171 ### Perform baseline.
172 my $filesystem = HoneyClient::Agent::Integrity::Filesystem->new(monitored_directories => [ $monitor_dir ],
173                                                                 ignored_entries       => [ $monitor_dir ]);
174
175 ### Change data in our test directory on the filesystem.
176 # Delete the target test file.
177 if (!unlink($delete_file)) {
178     fail("Unable to delete test file '" . $delete_file . "'.");
179 }
180
181 # Add the target test file.
182 open(ADD_FILE, ">", $add_file) or BAIL_OUT("Unable to create test file '" . $add_file . "'.");
183 print ADD_FILE $add_string;
184 close ADD_FILE;
185
186 my $md5_ctx = Digest::MD5->new();
187 my $sha1_ctx = Digest::SHA->new("1");
188 my $type_ctx = File::Type->new();
189
190 my $add_fh = IO::File->new($add_file, "r");
191 $md5_ctx->addfile($add_fh);
192 my $add_file_md5 = $md5_ctx->hexdigest();
193 seek($add_fh, 0, 0);
194 $sha1_ctx->addfile($add_fh);
195 my $add_file_sha1 = $sha1_ctx->hexdigest();
196 undef $add_fh;
197 my $add_file_type = $type_ctx->mime_type($add_file);
198
199 @file_attr = stat($add_file);
200 my $add_file_size  = $file_attr[7];
201 my $add_file_mtime = $file_attr[9];
202
203 # Change the target test file.
204 open(CHANGE_FILE, ">", $change_file) or BAIL_OUT("Unable to create test file '" . $change_file . "'.");
205 print CHANGE_FILE $change_string2;
206 close CHANGE_FILE;
207
208 my $change_fh = IO::File->new($change_file, "r");
209 $md5_ctx->addfile($change_fh);
210 my $change_file_md5 = $md5_ctx->hexdigest();
211 seek($change_fh, 0, 0);
212 $sha1_ctx->addfile($change_fh);
213 my $change_file_sha1 = $sha1_ctx->hexdigest();
214 undef $change_fh;
215 my $change_file_type = $type_ctx->mime_type($change_file);
216
217 @file_attr = stat($change_file);
218 my $change_file_size2  = $file_attr[7];
219 my $change_file_mtime2 = $file_attr[9];
220
221 ### Perform check.
222 my $foundChanges = $filesystem->check(no_prepare => 1);
223
224 # Uncomment these lines, if you want to see more
225 # detailed information about the changes found.
226 #$Data::Dumper::Terse = 0;
227 #$Data::Dumper::Indent = 1;
228 #diag(Dumper($foundChanges));
229
230 ### Verify changes.
231 my $expectedChanges = [
232   {
233     'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_MODIFIED,
234     'new' => {
235         'name'  => $change_file,
236         'size'  => $change_file_size2,
237         'mtime' => $change_file_mtime2,
238     },
239     'old' => {
240         'name'  => $change_file,
241         'size'  => $change_file_size1,
242         'mtime' => $change_file_mtime1,
243     },
244   },
245   {
246     'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_ADDED,
247     'new' => {
248         'name'  => $add_file,
249         'size'  => $add_file_size,
250         'mtime' => $add_file_mtime,
251     },
252   },
253   {
254     'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_DELETED,
255     'old' => {
256         'name'  => $delete_file,
257         'size'  => $delete_file_size,
258         'mtime' => $delete_file_mtime,
259     },
260   },
261 ];
262
263 is_deeply($foundChanges, $expectedChanges, "check(no_prepare => 1)") or diag("The check() call failed.");
264
265 ### Perform check.
266 $foundChanges = $filesystem->check();
267
268 # Uncomment these lines, if you want to see more
269 # detailed information about the changes found.
270 #$Data::Dumper::Terse = 0;
271 #$Data::Dumper::Indent = 1;
272 #diag(Dumper($foundChanges));
273
274 ### Verify changes.
275 $expectedChanges = [
276   {
277     'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_MODIFIED,
278     'name'  => HoneyClient::Agent::Integrity::Filesystem::_convertFilename($change_file),
279     'mtime' => HoneyClient::Agent::Integrity::Filesystem::_convertTime($change_file_mtime2),
280     'content' => {
281         'size'  => $change_file_size2,
282         'type'  => $change_file_type,
283         'sha1'  => $change_file_sha1,
284         'md5'   => $change_file_md5,
285     },
286   },
287   {
288     'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_ADDED,
289     'name'  => HoneyClient::Agent::Integrity::Filesystem::_convertFilename($add_file),
290     'mtime' => HoneyClient::Agent::Integrity::Filesystem::_convertTime($add_file_mtime),
291     'content' => {
292         'size'  => $add_file_size,
293         'type'  => $add_file_type,
294         'sha1'  => $add_file_sha1,
295         'md5'   => $add_file_md5,
296     },
297   },
298   {
299     'status' => $HoneyClient::Agent::Integrity::Filesystem::STATUS_DELETED,
300     'name'  => HoneyClient::Agent::Integrity::Filesystem::_convertFilename($delete_file),
301     'mtime' => HoneyClient::Agent::Integrity::Filesystem::_convertTime($delete_file_mtime),
302   },
303 ];
304
305 is_deeply($foundChanges, $expectedChanges, "check()") or diag("The check() call failed.");
306
307 ### Clean up test data.
308 close DELETE_FILE;
309 unlink($delete_file);
310
311 close CHANGE_FILE;
312 unlink($change_file);
313
314 close ADD_FILE;
315 unlink($add_file);
316 }
317
318
319
320
321 1;
Note: See TracBrowser for help on using the browser.