Changeset 596
- Timestamp:
- 06/21/07 16:02:55 (1 year ago)
- Files:
-
- honeyclient/branches/exp/mbriggs-db/etc/honeyclient.xml (modified) (1 diff)
- honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Agent/Driver/Browser.pm (modified) (6 diffs)
- honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Agent/Integrity/Filesystem.pm (modified) (5 diffs)
- honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager.pm (modified) (1 diff)
- honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/VM.pm (modified) (3 diffs)
- honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/VM/Clone.pm (modified) (17 diffs)
- honeyclient/branches/exp/mbriggs-db/t/honeyclient_manager_vm.t (modified) (3 diffs)
- honeyclient/branches/exp/mbriggs-db/t/honeyclient_manager_vm_clone.t (modified) (3 diffs)
- honeyclient/branches/exp/mbriggs-db/t/test_vm/nvram (modified) (previous)
- honeyclient/branches/exp/mbriggs-db/t/test_vm/winXPPro.vmx (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
honeyclient/branches/exp/mbriggs-db/etc/honeyclient.xml
r587 r596 430 430 <!-- HoneyClient::Manager::VM Options --> 431 431 <VM> 432 <!-- Note: This port should be unique and not already in use by other modules, services, or daemons running on the host system. --> 433 <port description="The TCP port number that the SOAP server for all Manager modules will listen on for requests." default="8089"> 432 <master_vm_config description="The full absolute path to the VM configuration file on the host system that will be used by all subsequent cloned VMs."> 433 /vm/master-vms/Agent.Master-20/winXPPro.cfg 434 </master_vm_config> 435 <port description="The TCP port number that the SOAP server of the VM daemon will listen on for requests. Note: This port should be unique and not already be used by other modules, services, or daemons running on the host system." default="8089"> 434 436 8089 435 437 </port> honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Agent/Driver/Browser.pm
r536 r596 904 904 the "DEFAULT PARAMETER LIST" section. 905 905 906 Once a drive() iteration has completed, the corresponding browser process 907 is terminated. Thus, each call to drive() invokes a new instance of the 906 Once a drive() iteration has completed, the corresponding browser process 907 is terminated. Thus, each call to drive() invokes a new instance of the 908 908 browser. 909 909 … … 1278 1278 sub _scoreLinks { 1279 1279 my ($base, $content, %wordlists) = @_; 1280 my @good_words = @{$wordlists{good}};1281 my @bad_words = @{$wordlists{bad}};1280 my @good_words = @{$wordlists{good}}; 1281 my @bad_words = @{$wordlists{bad}}; 1282 1282 my %links = (); 1283 1283 my $url; … … 1285 1285 # If the page is blank, there is no point trying to parse it 1286 1286 if (!$content) { 1287 return %links;1287 return keys(%links); 1288 1288 } 1289 1289 1290 # Begin to scour the HTML content for <a> tags, parsing attributes and text 1291 while ($content =~ m{<a\b([^>]+)>(.*?)</a>}ig) { 1292 my $attr = $1; 1293 my $text = $2; 1290 # Begin to scour the HTML content for tags, parsing attributes and text 1291 # Any tag which has an HREF, IMG, or SRC attribute could potentially 1292 # have a url of interest, either for scoring or for punching a hole in 1293 # the firewall. 1294 while ($content =~ m{<(IFRAME|A|LINK|IMG|OBJECT|EMBED|SCRIPT)\b([^>]+)>(.*?)</(\1)>}sig) { 1295 my $attr = $2; 1296 my $text = $3; 1294 1297 my $score = 0; 1295 1298 1296 1299 # Look for the link in the attribute data 1297 if ($attr =~ m{1298 \b HREF 1299 \s* = \s*1300 (?:1301 "([^"]*)"1302 |1303 '([^']*)'1304 |1305 {[^'">\s]+}1306 )1307 }xi)1308 {1300 if ($attr =~ m{ 1301 \b (HREF|SRC|USEMAP|CLASSID|DATA) 1302 \s* = \s* 1303 (?: 1304 "([^"]*)" 1305 | 1306 '([^']*)' 1307 | 1308 {[^'">\s]+} 1309 ) 1310 }six) 1311 { 1309 1312 $url = $+; 1310 1313 … … 1320 1323 $url = url($url, $base)->abs; 1321 1324 1322 # The link must be an HREF and be a http(s) link 1323 if ($url =~ /^http/i) { 1324 # Begin scoring the link based on surrounding context 1325 # This can be improved/customized in many different ways. 1326 # Our implementation is only one possible way to assign 1327 # values to the context elements. 1328 1329 # Score length of link text. These are arbitrary lengths, but 1330 # the reasoning is that really short text links are not too 1331 # visible (we are excluding image links from this criteria), 1332 # and really long text would be weird or abnormal to the human 1333 # web surfer. 1334 if ($text !~ /img /i && 1335 length($text) > $min_text_length && 1336 length($text) < $max_text_length) { 1337 $score += length($text); 1338 } 1339 1340 # Score the image content, if it exists 1341 # We score the size proportional to a 1024 X 768 display 1342 # Image bonus 1343 if ($text =~ /img /i) { 1344 $score += $image_bonus; 1345 } 1346 # Score image size 1347 my $width; 1348 my $height; 1349 if ($text =~ /\b WIDTH\s*=\s*.(\d+)/xi) { 1350 $width = $1; 1351 } 1352 if ($text =~ /\b HEIGHT\s*=\s*.(\d+)/xi) { 1353 $height = $1; 1354 } 1355 if ($width && $height) { 1356 $score += int(($width*$height)/($default_display_size)*100); 1357 } 1358 elsif ($width) { 1359 $score += int($width/10); 1360 } 1361 elsif ($height) { 1362 $score += int($height/10); 1363 } 1364 1365 # Good word bonus 1366 foreach (@good_words) { 1367 if ($text =~ /$_/i) { 1368 $score += $word_value; 1369 } 1370 } 1371 1372 # Bad word penalty 1373 foreach (@bad_words) { 1374 if ($text =~ /$_/i) { 1375 $score -= $word_value; 1376 } 1377 } 1378 1379 # Put it in the return value hash and zero the score 1380 $links{$url} = $score; 1381 $url = undef; 1325 # Begin scoring the link based on surrounding context 1326 # This can be improved/customized in many different ways. 1327 # Our implementation is only one possible way to assign 1328 # values to the context elements. 1329 1330 my $width; 1331 my $height; 1332 # Score the size of an object based on width and height 1333 if ($attr =~ /\b WIDTH\s*=\s*.(\d+)/xi) { 1334 $width = $1; 1382 1335 } 1336 if ($attr =~ /\b HEIGHT\s*=\s*.(\d+)/xi) { 1337 $height = $1; 1338 } 1339 if ($width && $height) { 1340 $score += int(($width*$height)/($default_display_size)*100); 1341 } 1342 elsif ($width) { 1343 $score += int($width/10); 1344 } 1345 elsif ($height) { 1346 $score += int($height/10); 1347 } 1348 1349 # Score length of link text. These are arbitrary lengths, but 1350 # the reasoning is that really short text links are not too 1351 # visible (we are excluding image links from this criteria), 1352 # and really long text would be weird or abnormal to the human 1353 # web surfer. 1354 if ($text !~ /img /i && 1355 length($text) > $min_text_length && 1356 length($text) < $max_text_length) { 1357 $score += length($text); 1358 } 1359 1360 # Score the image content, if it exists 1361 # We score the size proportional to a 1024 X 768 display 1362 # Image bonus 1363 if ($text =~ /img /i) { 1364 $score += $image_bonus; 1365 } 1366 # Score image size 1367 $width = undef; 1368 $height = undef; 1369 if ($text =~ /\b WIDTH\s*=\s*.(\d+)/xi) { 1370 $width = $1; 1371 } 1372 if ($text =~ /\b HEIGHT\s*=\s*.(\d+)/xi) { 1373 $height = $1; 1374 } 1375 if ($width && $height) { 1376 $score += int(($width*$height)/($default_display_size)*100); 1377 } 1378 elsif ($width) { 1379 $score += int($width/10); 1380 } 1381 elsif ($height) { 1382 $score += int($height/10); 1383 } 1384 1385 # Good word bonus 1386 foreach (@good_words) { 1387 if ($text =~ /$_/i) { 1388 $score += $word_value; 1389 } 1390 } 1391 1392 # Bad word penalty 1393 foreach (@bad_words) { 1394 if ($text =~ /$_/i) { 1395 $score -= $word_value; 1396 } 1397 } 1398 1399 # Put it in the return value hash and zero the score 1400 $links{$url} = $score; 1401 $url = undef; 1383 1402 } 1384 1403 } … … 1392 1411 =over 4 1393 1412 1394 Indicates if the Browser driver B<$object> has driven the browser 1413 Indicates if the Browser driver B<$object> has driven the browser 1395 1414 process to all possible links it has found within its hashtables 1396 1415 and is unable to navigate the browser further without additional, external … … 1504 1523 my $next_link_is_set = 0; 1505 1524 if (defined($self->next_link_to_visit)) { 1506 $next_link_is_set = 1; 1525 $next_link_is_set = 1; 1507 1526 } 1508 1527 honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Agent/Integrity/Filesystem.pm
r513 r596 433 433 } 434 434 435 # A helper callback function, designed to populate the @file_analysis436 # global array with hashtable entries about filesystem objects.435 # A helper callback function, designed to populate the $file_analysis 436 # global array reference with hashtable entries about filesystem objects. 437 437 # 438 438 # Input: none … … 444 444 # Create a new entry. 445 445 my $entry = { 446 name => $File::Find::name,447 size => $attr[7],448 mtime => $attr[9],446 name => defined($File::Find::name) ? $File::Find::name : 'UNKNOWN', 447 size => defined($attr[7]) ? $attr[7] : 0, 448 mtime => defined($attr[9]) ? $attr[9] : 0, 449 449 }; 450 450 … … 935 935 next; 936 936 937 # If the entry is a symlink. 938 } elsif (-l $fh) { 939 $type = "symlink"; 940 undef $fh; 941 942 # XXX: We currently skip all entries that 943 # only correspond to symlinks. 944 # This is a known limitation. 945 next; 946 937 947 # If the entry is a file. 938 948 } else { … … 990 1000 # Output: absolute windows filename path 991 1001 sub _convertFilename { 992 return lc(fullwin32path(shift)); 1002 my $path = shift; 1003 1004 # Unfortunately Filesys::CygwinPaths seems to like 1005 # to follow symbolic links, when resolving win32 paths. 1006 # This is bad. To counter this, we make sure the filename 1007 # we give it isn't a valid symlink so that it can properly 1008 # perform the conversion. 1009 if (-l $path) { 1010 $path .= "*"; 1011 $path = lc(fullwin32path($path)); 1012 chop($path); 1013 return $path; 1014 } else { 1015 return lc(fullwin32path($path)); 1016 } 993 1017 } 994 1018 … … 1413 1437 1414 1438 This library also only monitors B<FILE> changes. Thus, if malware 1415 manipulates B<EMPTY DIRECTORIES> o n the system, then this library will1416 B<NOT> report those changes.1439 manipulates B<EMPTY DIRECTORIES> or B<SYMLINKS> on the system, then 1440 this library will B<NOT> report those changes. 1417 1441 1418 1442 =head1 SEE ALSO honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager.pm
r518 r596 722 722 my $vmCfg = $vmCloneConfig; 723 723 $vmCloneConfig = undef; 724 $LOG->info("Calling destroyVM(config => " . $vmCfg . ").");725 $stubVM-> destroyVM(config => $vmCfg);724 $LOG->info("Calling suspendVM(config => " . $vmCfg . ")."); 725 $stubVM->suspendVM(config => $vmCloneConfig); 726 726 print "Done!\n"; 727 727 _cleanup(); honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/VM.pm
r416 r596 355 355 =begin testing 356 356 357 # Make sure ExtUtils::MakeMaker loads. 358 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."); } 359 require_ok('ExtUtils::MakeMaker'); 360 can_ok('ExtUtils::MakeMaker', 'prompt'); 361 use ExtUtils::MakeMaker qw(prompt); 362 357 363 # Generate a notice, to clarify our assumptions. 358 diag("Note: These unit tests *expect* the VMware Server / GSX daemon to be operational on this system beforehand."); 364 diag("About to run basic unit tests."); 365 diag("Note: These tests *expect* VMware Server or VMware GSX to be installed and running on this system beforehand."); 366 367 my $question; 368 $question = prompt("# Do you want to run basic tests?", "yes"); 369 if ($question !~ /^y.*/i) { 370 exit; 371 } 359 372 360 373 # Make sure Log::Log4perl loads … … 500 513 use Thread::Semaphore; 501 514 502 # TODO: Remove this once unit testing should actually be used. 503 # Ideally, this should be handled programmatically, based upon user prompt. 504 #exit; 505 515 diag("About to run extended tests."); 506 516 # Generate a notice, to inform the tester that these tests are not 507 517 # exactly quick. 508 diag("Note: These unit tests will take *significant* time to complete (10-30 minutes)."); 518 diag("Note: These extended tests will take *significant* time to complete (10-30 minutes)."); 519 520 my $question = prompt("# Do you want to run extended tests?", "no"); 521 if ($question !~ /^y.*/i) { 522 exit; 523 } 509 524 510 525 =end testing … … 3888 3903 # this question, if need be. 3889 3904 if ($som->result == VM_EXECUTION_STATE_STUCK) { 3890 $som = $stub->answerVM(config => $ cloneVM);3905 $som = $stub->answerVM(config => $masterVM); 3891 3906 } 3892 3907 honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/VM/Clone.pm
r516 r596 112 112 use strict; 113 113 use warnings; 114 use Config; 114 115 use Carp (); 115 116 … … 153 154 # Symbols to autoexport (:DEFAULT tag) 154 155 @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); 156 157 # Check to see if ithreads are compiled into this version of Perl. 158 if (!$Config{useithreads}) { 159 Carp::croak "Error: Recompile Perl with ithread support, in order to use this module.\n"; 160 } 155 161 156 162 $SIG{PIPE} = 'IGNORE'; # Do not exit on broken pipes. … … 196 202 use HoneyClient::Util::Config qw(getVar); 197 203 198 # XXX: FIX THIS 204 # Make sure HoneyClient::Util::SOAP loads. 205 BEGIN { use_ok('HoneyClient::Util::SOAP', qw(getClientHandle)) or diag("Can't load HoneyClient::Util::SOAP package. Check to make sure the package library is correctly listed within the path."); } 206 require_ok('HoneyClient::Util::SOAP'); 207 can_ok('HoneyClient::Util::SOAP', 'getClientHandle'); 208 use HoneyClient::Util::SOAP qw(getClientHandle); 209 210 # Make sure HoneyClient::Manager::VM loads. 211 BEGIN { use_ok('HoneyClient::Manager::VM') or diag("Can't load HoneyClient::Manager:VM package. Check to make sure the package library is correctly listed within the path."); } 212 require_ok('HoneyClient::Manager::VM'); 213 use HoneyClient::Manager::VM; 214 215 # Make sure VMware::VmPerl loads. 216 BEGIN { use_ok('VMware::VmPerl', qw(VM_EXECUTION_STATE_ON VM_EXECUTION_STATE_OFF VM_EXECUTION_STATE_STUCK VM_EXECUTION_STATE_SUSPENDED)) or diag("Can't load VMware::VmPerl package. Check to make sure the package library is correctly listed within the path."); } 217 require_ok('VMware::VmPerl'); 218 use VMware::VmPerl qw(VM_EXECUTION_STATE_ON VM_EXECUTION_STATE_OFF VM_EXECUTION_STATE_STUCK VM_EXECUTION_STATE_SUSPENDED); 219 199 220 # Make sure the module loads properly, with the exportable 200 221 # functions shared. 201 BEGIN { use_ok('HoneyClient::Agent::Driver') or diag("Can't load HoneyClient::Agent::Driver package. Check to make sure the package library is correctly listed within the path."); } 202 require_ok('HoneyClient::Agent::Driver'); 203 can_ok('HoneyClient::Agent::Driver', 'new'); 204 can_ok('HoneyClient::Agent::Driver', 'drive'); 205 can_ok('HoneyClient::Agent::Driver', 'isFinished'); 206 can_ok('HoneyClient::Agent::Driver', 'next'); 207 can_ok('HoneyClient::Agent::Driver', 'status'); 208 use HoneyClient::Agent::Driver; 222 BEGIN { use_ok('HoneyClient::Manager::VM::Clone') or diag("Can't load HoneyClient::Manager::VM::Clone package. Check to make sure the package library is correctly listed within the path."); } 223 require_ok('HoneyClient::Manager::VM::Clone'); 224 use HoneyClient::Manager::VM::Clone; 209 225 210 226 # Suppress all logging messages, since we need clean output for unit testing. … … 223 239 use Storable qw(dclone); 224 240 241 # Make sure threads loads. 242 BEGIN { use_ok('threads') or diag("Can't load threads package. Check to make sure the package library is correctly listed within the path."); } 243 require_ok('threads'); 244 use threads; 245 246 # Make sure threads::shared loads. 247 BEGIN { use_ok('threads::shared') or diag("Can't load threads::shared package. Check to make sure the package library is correctly listed within the path."); } 248 require_ok('threads::shared'); 249 use threads::shared; 250 251 # Make sure File::Basename loads. 252 BEGIN { use_ok('File::Basename', qw(dirname basename)) or diag("Can't load File::Basename package. Check to make sure the package library is correctly listed within the path."); } 253 require_ok('File::Basename'); 254 can_ok('File::Basename', 'dirname'); 255 can_ok('File::Basename', 'basename'); 256 use File::Basename qw(dirname basename); 257 225 258 =end testing 226 259 … … 228 261 229 262 ####################################################################### 263 264 # Include Threading Library 265 use threads; 266 use threads::shared; 230 267 231 268 # Include Global Configuration Processing Library 232 269 use HoneyClient::Util::Config qw(getVar); 233 270 271 # Include SOAP Library 272 use HoneyClient::Util::SOAP qw(getClientHandle); 273 274 # Include VM Libraries 275 use VMware::VmPerl qw(VM_EXECUTION_STATE_ON 276 VM_EXECUTION_STATE_OFF 277 VM_EXECUTION_STATE_STUCK 278 VM_EXECUTION_STATE_SUSPENDED); 279 use HoneyClient::Manager::VM; 280 234 281 # Use Storable Library 235 282 use Storable qw(dclone); … … 243 290 # The global logging object. 244 291 our $LOG = get_logger(); 292 293 # The global variable, used to count the number of 294 # Clone objects that have been created. 295 our $OBJECT_COUNT = 0; 245 296 246 297 =pod … … 259 310 $object->{key} = $value; # Sets key's value. 260 311 261 =head2 bypass_clone312 =head2 master_vm_config 262 313 263 314 =over 4 264 315 265 When set to 1, the object will forgo any type of initial cloning 266 operation, upon initialization. Otherwise, cloning will occur 267 as normal, upon initialization. 316 The full absolute path to the master VM's configuration file, whose 317 contents will be the basis for each subsequently cloned VM. 268 318 269 319 =back … … 272 322 273 323 my %PARAMS = ( 274 # When set to 1, the object will forgo any type of initial cloning 275 # operation, upon initialization. Otherwise, cloning will occur 276 # as normal, upon initialization. 277 bypass_clone => 0, 324 # The full absolute path to the master VM's configuration file, whose 325 # contents will be the basis for each subsequently cloned VM. 326 master_vm_config => getVar(name => "master_vm_config"), 327 328 # A SOAP handle to the VM manager daemon. (This internal variable 329 # should never be modified externally.) 330 _vm_handle => undef, 278 331 ); 279 332 … … 340 393 # mechanism. 341 394 sub DESTROY { 395 # Decrement our global object count. 396 $OBJECT_COUNT--; 397 398 # Upon last use, destroy the global instance of the VM manager. 399 if ($OBJECT_COUNT <= 0) { 400 HoneyClient::Manager::VM->destroy(); 401 } 342 402 } 343 403 … … 352 412 The following functions have been implemented by any Clone object. 353 413 354 =head2 HoneyClient:: Agent::Driver->new($param => $value, ...)414 =head2 HoneyClient::Manager::VM::Clone->new($param => $value, ...) 355 415 356 416 =over 4 … … 358 418 Creates a new Clone object, which contains a hashtable 359 419 containing any of the supplied "param => value" arguments. 360 Upon creation, the Clone object clones the supplied master VM.361 420 362 421 I<Inputs>: … … 373 432 =begin testing 374 433 375 # Create a generic clone, with test state data. 376 my $clone = HoneyClient::Manager::VM::Clone->new(test => 1, bypass_clone => 1); 377 is($clone->{test}, 1, "new(test => 1, bypass_clone => 1)") or diag("The new() call failed."); 378 isa_ok($clone, 'HoneyClient::Manager::VM::Clone', "new(test => 1, bypass_clone => 1)") or diag("The new() call failed."); 379 380 # TODO: Need more comprehensive test, where the clone actually gets created. 434 # Shared test variables. 435 my ($stub, $som, $URL); 436 my $testVM = $ENV{PWD} . "/" . getVar(name => "test_vm_config", 437 namespace => "HoneyClient::Manager::VM::Test"); 438 439 # Catch all errors, in order to make sure child processes are 440 # properly killed. 441 eval { 442 443 $URL = HoneyClient::Manager::VM->init(); 444 445 # Connect to daemon as a client. 446 $stub = getClientHandle(namespace => "HoneyClient::Manager::VM"); 447 448 # In order to test setMasterVM(), we're going to fully clone 449 # the testVM, then set the newly created clone as a master VM. 450 451 # Get the test VM's parent directory, 452 # in order to create a temporary master VM. 453 my $testVMDir = dirname($testVM); 454 my $masterVMDir = dirname($testVMDir) . "/test_vm_master"; 455 my $masterVM = $masterVMDir . "/" . basename($testVM); 456 457 # Create the master VM. 458 $som = $stub->fullCloneVM(src_config => $testVM, dest_dir => $masterVMDir); 459 460 # Wait a small amount of time for the asynchronous clone 461 # to complete. 462 sleep (60); 463 464 # The master VM should be on. 465 $som = $stub->getStateVM(config => $masterVM); 466 467 # Since the master VM doesn't have an OS installed on it, 468 # the VM may be considered stuck. Go ahead and answer 469 # this question, if need be. 470 if ($som->result == VM_EXECUTION_STATE_STUCK) { 471 $som = $stub->answerVM(config => $masterVM); 472 } 473 474 HoneyClient::Manager::VM->destroy(); 475 sleep (1); 476 477 # Create a generic clone, with test state data. 478 my $clone = HoneyClient::Manager::VM::Clone->new(test => 1, master_vm_config => $masterVM); 479 is($clone->{test}, 1, "new(test => 1, master_vm_config => '$masterVM')") or diag("The new() call failed."); 480 isa_ok($clone, 'HoneyClient::Manager::VM::Clone', "new(test => 1, master_vm_config => '$masterVM')") or diag("The new() call failed."); 481 482 # Destroy the master VM. 483 $som = $stub->destroyVM(config => $masterVM); 484 }; 485 486 # Kill the child daemon, if it still exists. 487 HoneyClient::Manager::VM->destroy(); 488 sleep (1); 489 490 # Report any failure found. 491 if ($@) { 492 fail($@); 493 } 381 494 382 495 =end testing … … 420 533 bless $self, $class; 421 534 422 # Perform baselining, if not bypassed. 423 # TODO: Finish this. 424 if (!$self->{'bypass_clone'}) { 425 $LOG->info("Cloning Master VM."); 426 #$self->_baseline(); 535 # Upon first use, start up a global instance of the VM manager. 536 if ($OBJECT_COUNT <= 0) { 537 HoneyClient::Manager::VM->init(); 427 538 } 539 540 # Set a valid handle for the VM daemon. 541 $self->{'_vm_handle'} = getClientHandle(namespace => "HoneyClient::Manager::VM"); 542 543 # Set the master VM. 544 $LOG->info("Setting VM (" . $self->{'master_vm_config'} . ") as master."); 545 my $som = $self->{'_vm_handle'}->setMasterVM(config => $self->{'master_vm_config'}); 546 if (!$som->result()) { 547 $LOG->fatal("Unable to set VM (" . $self->{'master_vm_config'} . ") as a master VM."); 548 Carp::croak "Unable to set VM (" . $self->{'master_vm_config'} . ") as a master VM."; 549 } 550 551 # Update our global object count. 552 $OBJECT_COUNT++; 428 553 429 554 # Finally, return the blessed object. … … 433 558 =pod 434 559 435 =head2 $object-> drive()560 =head2 $object->start() 436 561 437 562 =over 4 438 563 439 Drives the back-end application for one iteration, updating the 440 corresponding internal object state with information obtained 441 from driving this application for one iteration. 442 443 I<Output>: The updated Driver B<$object>, containing state information 444 from driving the application for one iteration. Will croak if 445 operation fails. 564 If not previously called, this method creates a new clone VM 565 from the supplied master VM. Furthermore, this method will power 566 on the clone, and wait until the clone VM has fully booted and 567 has an operational Agent daemon running on it. 568 569 During this power on process, the name, MAC address, and 570 IP address of the running clone are recorded in the object. 571 572 I<Output>: The updated Clone B<$object>, containing state information 573 from starting the clone VM. Will croak if this operation fails. 446 574 447 575 =back 448 576 449 =begin testing 450 577 # XXX: FINISH THIS 578 #=begin testing 579 # 451 580 # Create a generic driver, with test state data. 452 my $driver = HoneyClient::Agent::Driver->new(test => 1);453 dies_ok {$driver->drive()} 'drive()' or diag("The drive() call failed. Expected drive() to throw an exception.");454 455 =end testing581 #my $driver = HoneyClient::Agent::Driver->new(test => 1); 582 #dies_ok {$driver->drive()} 'drive()' or diag("The drive() call failed. Expected drive() to throw an exception."); 583 # 584 #=end testing 456 585 457 586 =cut 458 587 459 sub drive { 460 # Get the class name. 461 my $self = shift; 588 sub start { 589 # Extract arguments. 590 my ($self, %args) = @_; 591 592 # Sanity check: Make sure we've been fed an object. 593 unless (ref($self)) { 594 $LOG->error("Error: Function must be called in reference to a " . 595 __PACKAGE__ . "->new() object!"); 596 Carp::croak "Error: Function must be called in reference to a " . 597 __PACKAGE__ . "->new() object!"; 598 } 462 599 463 # Check to see if the class name is inherited or defined. 464 my $class = ref($self) || $self; 465 466 # Emit generic "not implemented" error message. 467 $LOG->error($class . "->drive() is not implemented!"); 468 Carp::croak "Error: " . $class . "->drive() is not implemented!\n"; 600 # Temporary variable to hold SOAP Object Message. 601 my $som = undef; 602 603 # Perform the quick clone operation. 604 $LOG->info("Quick cloning master VM (" . $self->{'master_vm_config'} . ")."); 605 $som = $self->{'_vm_handle'}->quickCloneVM(src_config => $self->{'master_vm_config'}); 606 if (!$som->result()) { 607 $LOG->fatal("Unable to quick clone master VM (" . $self->{'master_vm_config'} . ")."); 608 Carp::croak "Unable to quick clone master VM (" . $self->{'master_vm_config'} . ")."; 609 } 469 610 } 470 611 … … 483 624 =back 484 625 485 =begin testing486 626 #=begin testing 627 # 487 628 # Create a generic driver, with test state data. 488 my $driver = HoneyClient::Agent::Driver->new(test => 1);489 dies_ok {$driver->isFinished()} 'isFinished()' or diag("The isFinished() call failed. Expected isFinished() to throw an exception.");490 491 =end testing629 #my $driver = HoneyClient::Agent::Driver->new(test => 1); 630 #dies_ok {$driver->isFinished()} 'isFinished()' or diag("The isFinished() call failed. Expected isFinished() to throw an exception."); 631 # 632 #=end testing 492 633 493 634 =cut … … 568 709 =back 569 710 570 =begin testing571 711 #=begin testing 712 # 572 713 # Create a generic driver, with test state data. 573 my $driver = HoneyClient::Agent::Driver->new(test => 1);574 dies_ok {$driver->next()} 'next()' or diag("The next() call failed. Expected next() to throw an exception.");575 576 =end testing714 #my $driver = HoneyClient::Agent::Driver->new(test => 1); 715 #dies_ok {$driver->next()} 'next()' or diag("The next() call failed. Expected next() to throw an exception."); 716 # 717 #=end testing 577 718 578 719 =cut … … 651 792 =back 652 793 653 =begin testing654 794 #=begin testing 795 # 655 796 # Create a generic driver, with test state data. 656 my $driver = HoneyClient::Agent::Driver->new(test => 1);657 dies_ok {$driver->status()} 'status()' or diag("The status() call failed. Expected status() to throw an exception.");658 659 =end testing797 #my $driver = HoneyClient::Agent::Driver->new(test => 1); 798 #dies_ok {$driver->status()} 'status()' or diag("The status() call failed. Expected status() to throw an exception."); 799 # 800 #=end testing 660 801 661 802 =cut honeyclient/branches/exp/mbriggs-db/t/honeyclient_manager_vm.t
r416 r596 9 9 # =begin testing 10 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 11 17 # Generate a notice, to clarify our assumptions. 12 diag("Note: These unit tests *expect* the VMware Server / GSX daemon to be operational on this system beforehand."); 18 diag("About to run basic unit tests."); 19 diag("Note: These tests *expect* VMware Server or VMware GSX to be installed and running on this system beforehand."); 20 21 my $question; 22 $question = prompt("# Do you want to run basic tests?", "yes"); 23 if ($question !~ /^y.*/i) { 24 exit; 25 } 13 26 14 27 # Make sure Log::Log4perl loads … … 154 167 use Thread::Semaphore; 155 168 156 # TODO: Remove this once unit testing should actually be used. 157 # Ideally, this should be handled programmatically, based upon user prompt. 158 #exit; 159 169 diag("About to run extended tests."); 160 170 # Generate a notice, to inform the tester that these tests are not 161 171 # exactly quick. 162 diag("Note: These unit tests will take *significant* time to complete (10-30 minutes)."); 172 diag("Note: These extended tests will take *significant* time to complete (10-30 minutes)."); 173 174 my $question = prompt("# Do you want to run extended tests?", "no"); 175 if ($question !~ /^y.*/i) { 176 exit; 177 } 163 178 } 164 179 … … 1159 1174 # this question, if need be. 1160 1175 if ($som->result == VM_EXECUTION_STATE_STUCK) { 1161 $som = $stub->answerVM(config => $ cloneVM);1176 $som = $stub->answerVM(config => $masterVM); 1162 1177 } 1163 1178 honeyclient/branches/exp/mbriggs-db/t/honeyclient_manager_vm_clone.t
r536 r596 43 43 use HoneyClient::Util::Config qw(getVar); 44 44 45 # XXX: FIX THIS 45 # Make sure HoneyClient::Util::SOAP loads. 46 BEGIN { use_ok('HoneyClient::Util::SOAP', qw(getClientHandle)) or diag("Can't load HoneyClient::Util::SOAP package. Check to make sure the package library is correctly listed within the path."); } 47 require_ok('HoneyClient::Util::SOAP'); 48 can_ok('HoneyClient::Util::SOAP', 'getClientHandle'); 49 use HoneyClient::Util::SOAP qw(getClientHandle); 50 51 # Make sure HoneyClient::Manager::VM loads. 52 BEGIN { use_ok('HoneyClient::Manager::VM') or diag("Can't load HoneyClient::Manager:VM package. Check to make sure the package library is correctly listed within the path."); } 53 require_ok('HoneyClient::Manager::VM'); 54 use HoneyClient::Manager::VM; 55 56 # Make sure VMware::VmPerl loads. 57 BEGIN { use_ok('VMware::VmPerl', qw(VM_EXECUTION_STATE_ON VM_EXECUTION_STATE_OFF VM_EXECUTION_STATE_STUCK VM_EXECUTION_STATE_SUSPENDED)) or diag("Can't load VMware::VmPerl package. Check to make sure the package library is correctly listed within the path."); } 58 require_ok('VMware::VmPerl'); 59 use VMware::VmPerl qw(VM_EXECUTION_STATE_ON VM_EXECUTION_STATE_OFF VM_EXECUTION_STATE_STUCK VM_EXECUTION_STATE_SUSPENDED); 60 46 61 # Make sure the module loads properly, with the exportable 47 62 # functions shared. 48 BEGIN { use_ok('HoneyClient::Agent::Driver') or diag("Can't load HoneyClient::Agent::Driver package. Check to make sure the package library is correctly listed within the path."); } 49 require_ok('HoneyClient::Agent::Driver'); 50 can_ok('HoneyClient::Agent::Driver', 'new'); 51 can_ok('HoneyClient::Agent::Driver', 'drive'); 52 can_ok('HoneyClient::Agent::Driver', 'isFinished'); 53 can_ok('HoneyClient::Agent::Driver', 'next'); 54 can_ok('HoneyClient::Agent::Driver', 'status'); 55 use HoneyClient::Agent::Driver; 63 BEGIN { use_ok('HoneyClient::Manager::VM::Clone') or diag("Can't load HoneyClient::Manager::VM::Clone package. Check to make sure the package library is correctly listed within the path."); } 64 require_ok('HoneyClient::Manager::VM::Clone'); 65 use HoneyClient::Manager::VM::Clone; 56 66 57 67 # Suppress all logging messages, since we need clean output for unit testing. … … 69 79 can_ok('Storable', 'dclone'); 70 80 use Storable qw(dclone); 81 82 # Make sure threads loads. 83 BEGIN { use_ok('threads') or diag("Can't load threads package. Check to make sure the package library is correctly listed within the path."); } 84 require_ok('threads'); 85 use threads; 86 87 # Make sure threads::shared loads. 88 BEGIN { use_ok('threads::shared') or diag("Can't load threads::shared package. Check to make sure the package library is correctly listed within the path."); } 89 require_ok('threads::shared'); 90 use threads::shared; 91 92 # Make sure File::Basename loads. 93 BEGIN { use_ok('File::Basename', qw(dirname basename)) or diag("Can't load File::Basename package. Check to make sure the package library is correctly listed within the path."); } 94 require_ok('File::Basename'); 95 can_ok('File::Basename', 'dirname'); 96 can_ok('File::Basename', 'basename'); 97 use File::Basename qw(dirname basename); 71 98 } 72 99 … … 75 102 # =begin testing 76 103 { 77 # Create a generic clone, with test state data.78 my $clone = HoneyClient::Manager::VM::Clone->new(test => 1, bypass_clone => 1);79 is($clone->{test}, 1, "new(test => 1, bypass_clone => 1)") or diag("The new() call failed."); 80 isa_ok($clone, 'HoneyClient::Manager::VM::Clone', "new(test => 1, bypass_clone => 1)") or diag("The new() call failed.");104 # Shared test variables. 105 my ($stub, $som, $URL); 106 my $testVM = $ENV{PWD} . "/" . getVar(name => "test_vm_config", 107 namespace => "HoneyClient::Manager::VM::Test"); 81 108 82 # TODO: Need more comprehensive test, where the clone actually gets created. 109 # Catch all errors, in order to make sure child processes are 110 # properly killed. 111 eval { 112 113 $URL = HoneyClient::Manager::VM->init(); 114 115 # Connect to daemon as a client. 116 $stub = getClientHandle(namespace => "HoneyClient::Manager::VM"); 117 118 # In order to test setMasterVM(), we're going to fully clone 119 # the testVM, then set the newly created clone as a master VM. 120 121 # Get the test VM's parent directory, 122 # in order to create a temporary master VM. 123 my $testVMDir = dirname($testVM); 124 my $masterVMDir = dirname($testVMDir) . "/test_vm_master"; 125 my $masterVM = $masterVMDir . "/" . basename($testVM); 126 127 # Create the master VM. 128 $som = $stub->fullCloneVM(src_config => $testVM, dest_dir => $masterVMDir); 129 130 # Wait a small amount of time for the asynchronous clone 131 # to complete. 132 sleep (60); 133 134 # The master VM should be on. 135 $som = $stub->getStateVM(config => $masterVM); 136 137 # Since the master VM doesn't have an OS installed on it, 138 # the VM may be considered stuck. Go ahead and answer 139 # this question, if need be. 140 if ($som->result == VM_EXECUTION_STATE_STUCK) { 141 $som = $stub->answerVM(config => $masterVM); 142 } 143 144 HoneyClient::Manager::VM->destroy(); 145 sleep (1); 146 147 # Create a generic clone, with test state data. 148 my $clone = HoneyClient::Manager::VM::Clone->new(test => 1, master_vm_config => $masterVM); 149 is($clone->{test}, 1, "new(test => 1, master_vm_config => '$masterVM')") or diag("The new() call failed."); 150 isa_ok($clone, 'HoneyClient::Manager::VM::Clone', "new(test => 1, master_vm_config => '$masterVM')") or diag("The new() call failed."); 151 152 # Destroy the master VM. 153 $som = $stub->destroyVM(config => $masterVM); 154 }; 155 156 # Kill the child daemon, if it still exists. 157 HoneyClient::Manager::VM->destroy(); 158 sleep (1); 159 160 # Report any failure found. 161 if ($@) { 162 fail($@); 83 163 } 84 85 86 87 # =begin testing88 {89 # Create a generic driver, with test state data.90 my $driver = HoneyClient::Agent::Driver->new(test => 1);91 dies_ok {$driver->drive()} 'drive()' or diag("The drive() call failed. Expected drive() to throw an exception.");92 }93 94 95 96 # =begin testing97 {98 # Create a generic driver, with test state data.99 my $driver = HoneyClient::Agent::Driver->new(test => 1);100 dies_ok {$driver->isFinished()} 'isFinished()' or diag("The isFinished() call failed. Expected isFinished() to throw an exception.");101 }102 103 104 105 # =begin testing106 {107 # Create a generic driver, with test state data.108 my $driver = HoneyClient::Agent::Driver->new(test => 1);109 dies_ok {$driver->next()} 'next()' or diag("The next() call failed. Expected next() to throw an exception.");110 }111 112 113 114 # =begin testing115 {116 # Create a g
