root/honeyclient/branches/exp/xkovah-simpler_install/t/honeyclient_agent_integrity_filesystem.t

Revision 1008, 12.2 kB (checked in by kindlund, 1 year ago)

Merging kindlund-dynamic_updates branch back into trunk.

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