Changeset 596

Show
Ignore:
Timestamp:
06/21/07 16:02:55 (1 year ago)
Author:
kindlund
Message:

sc: merging branch using tags svn+ssh://kindlund@www.honeyclient.org/home/svn/honeyclient/honeyclient/tags/exp/UP7-mbriggs-db and svn+ssh://kindlund@www.honeyclient.org/home/svn/honeyclient/honeyclient/trunk

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • honeyclient/branches/exp/mbriggs-db/etc/honeyclient.xml

    r587 r596  
    430430        <!-- HoneyClient::Manager::VM Options --> 
    431431        <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"> 
    434436                8089 
    435437            </port> 
  • honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Agent/Driver/Browser.pm

    r536 r596  
    904904the "DEFAULT PARAMETER LIST" section. 
    905905 
    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  
     906Once a drive() iteration has completed, the corresponding browser process 
     907is terminated.  Thus, each call to drive() invokes a new instance of the 
    908908browser. 
    909909 
     
    12781278sub _scoreLinks { 
    12791279    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}}; 
    12821282    my %links = (); 
    12831283    my $url; 
     
    12851285    # If the page is blank, there is no point trying to parse it 
    12861286    if (!$content) { 
    1287         return %links
     1287        return keys(%links)
    12881288    } 
    12891289 
    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; 
    12941297        my $score = 0; 
    12951298 
    12961299        # 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       
    13091312            $url = $+; 
    13101313 
     
    13201323            $url = url($url, $base)->abs; 
    13211324 
    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; 
    13821335            } 
     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; 
    13831402        } 
    13841403    } 
     
    13921411=over 4 
    13931412 
    1394 Indicates if the Browser driver B<$object> has driven the browser   
     1413Indicates if the Browser driver B<$object> has driven the browser 
    13951414process to all possible links it has found within its hashtables 
    13961415and is unable to navigate the browser further without additional, external 
     
    15041523    my $next_link_is_set = 0; 
    15051524    if (defined($self->next_link_to_visit)) { 
    1506         $next_link_is_set = 1;  
     1525        $next_link_is_set = 1; 
    15071526    } 
    15081527 
  • honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Agent/Integrity/Filesystem.pm

    r513 r596  
    433433} 
    434434 
    435 # A helper callback function, designed to populate the @file_analysis 
    436 # 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. 
    437437# 
    438438# Input: none 
     
    444444    # Create a new entry. 
    445445    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
    449449    }; 
    450450 
     
    935935                    next; 
    936936 
     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 
    937947                # If the entry is a file. 
    938948                } else { 
     
    9901000# Output: absolute windows filename path 
    9911001sub _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    } 
    9931017} 
    9941018 
     
    14131437 
    14141438This library also only monitors B<FILE> changes.  Thus, if malware 
    1415 manipulates B<EMPTY DIRECTORIES> on the system, then this library will 
    1416 B<NOT> report those changes. 
     1439manipulates B<EMPTY DIRECTORIES> or B<SYMLINKS> on the system, then 
     1440this library will B<NOT> report those changes. 
    14171441 
    14181442=head1 SEE ALSO 
  • honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager.pm

    r518 r596  
    722722                        my $vmCfg = $vmCloneConfig; 
    723723                        $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); 
    726726                        print "Done!\n"; 
    727727                        _cleanup(); 
  • honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/VM.pm

    r416 r596  
    355355=begin testing 
    356356 
     357# Make sure ExtUtils::MakeMaker loads. 
     358BEGIN { 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."); } 
     359require_ok('ExtUtils::MakeMaker'); 
     360can_ok('ExtUtils::MakeMaker', 'prompt'); 
     361use ExtUtils::MakeMaker qw(prompt); 
     362 
    357363# 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."); 
     364diag("About to run basic unit tests."); 
     365diag("Note: These tests *expect* VMware Server or VMware GSX to be installed and running on this system beforehand."); 
     366 
     367my $question; 
     368$question = prompt("# Do you want to run basic tests?", "yes"); 
     369if ($question !~ /^y.*/i) { 
     370    exit; 
     371
    359372 
    360373# Make sure Log::Log4perl loads 
     
    500513use Thread::Semaphore; 
    501514 
    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  
     515diag("About to run extended tests."); 
    506516# Generate a notice, to inform the tester that these tests are not 
    507517# exactly quick. 
    508 diag("Note: These unit tests will take *significant* time to complete (10-30 minutes)."); 
     518diag("Note: These extended tests will take *significant* time to complete (10-30 minutes)."); 
     519 
     520my $question = prompt("# Do you want to run extended tests?", "no"); 
     521if ($question !~ /^y.*/i) { 
     522    exit; 
     523
    509524 
    510525=end testing 
     
    38883903    # this question, if need be. 
    38893904    if ($som->result == VM_EXECUTION_STATE_STUCK) { 
    3890         $som = $stub->answerVM(config => $cloneVM); 
     3905        $som = $stub->answerVM(config => $masterVM); 
    38913906    } 
    38923907 
  • honeyclient/branches/exp/mbriggs-db/lib/HoneyClient/Manager/VM/Clone.pm

    r516 r596  
    112112use strict; 
    113113use warnings; 
     114use Config; 
    114115use Carp (); 
    115116 
     
    153154    # Symbols to autoexport (:DEFAULT tag) 
    154155    @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    } 
    155161 
    156162    $SIG{PIPE} = 'IGNORE'; # Do not exit on broken pipes. 
     
    196202use HoneyClient::Util::Config qw(getVar); 
    197203 
    198 # XXX: FIX THIS 
     204# Make sure HoneyClient::Util::SOAP loads. 
     205BEGIN { 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."); } 
     206require_ok('HoneyClient::Util::SOAP'); 
     207can_ok('HoneyClient::Util::SOAP', 'getClientHandle'); 
     208use HoneyClient::Util::SOAP qw(getClientHandle); 
     209 
     210# Make sure HoneyClient::Manager::VM loads. 
     211BEGIN { 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."); } 
     212require_ok('HoneyClient::Manager::VM'); 
     213use HoneyClient::Manager::VM; 
     214 
     215# Make sure VMware::VmPerl loads. 
     216BEGIN { 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."); } 
     217require_ok('VMware::VmPerl'); 
     218use VMware::VmPerl qw(VM_EXECUTION_STATE_ON VM_EXECUTION_STATE_OFF VM_EXECUTION_STATE_STUCK VM_EXECUTION_STATE_SUSPENDED); 
     219 
    199220# Make sure the module loads properly, with the exportable 
    200221# 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; 
     222BEGIN { 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."); } 
     223require_ok('HoneyClient::Manager::VM::Clone'); 
     224use HoneyClient::Manager::VM::Clone; 
    209225 
    210226# Suppress all logging messages, since we need clean output for unit testing. 
     
    223239use Storable qw(dclone); 
    224240 
     241# Make sure threads loads. 
     242BEGIN { use_ok('threads') or diag("Can't load threads package.  Check to make sure the package library is correctly listed within the path."); } 
     243require_ok('threads'); 
     244use threads; 
     245 
     246# Make sure threads::shared loads. 
     247BEGIN { 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."); } 
     248require_ok('threads::shared'); 
     249use threads::shared; 
     250 
     251# Make sure File::Basename loads. 
     252BEGIN { 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."); } 
     253require_ok('File::Basename'); 
     254can_ok('File::Basename', 'dirname'); 
     255can_ok('File::Basename', 'basename'); 
     256use File::Basename qw(dirname basename); 
     257 
    225258=end testing 
    226259 
     
    228261 
    229262####################################################################### 
     263 
     264# Include Threading Library 
     265use threads; 
     266use threads::shared; 
    230267 
    231268# Include Global Configuration Processing Library 
    232269use HoneyClient::Util::Config qw(getVar); 
    233270 
     271# Include SOAP Library 
     272use HoneyClient::Util::SOAP qw(getClientHandle); 
     273 
     274# Include VM Libraries 
     275use VMware::VmPerl qw(VM_EXECUTION_STATE_ON 
     276                      VM_EXECUTION_STATE_OFF 
     277                      VM_EXECUTION_STATE_STUCK 
     278                      VM_EXECUTION_STATE_SUSPENDED); 
     279use HoneyClient::Manager::VM; 
     280 
    234281# Use Storable Library 
    235282use Storable qw(dclone); 
     
    243290# The global logging object. 
    244291our $LOG = get_logger(); 
     292 
     293# The global variable, used to count the number of 
     294# Clone objects that have been created. 
     295our $OBJECT_COUNT = 0; 
    245296 
    246297=pod 
     
    259310  $object->{key} = $value;    # Sets key's value. 
    260311 
    261 =head2 bypass_clone 
     312=head2 master_vm_config 
    262313 
    263314=over 4 
    264315 
    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. 
     316The full absolute path to the master VM's configuration file, whose 
     317contents will be the basis for each subsequently cloned VM. 
    268318 
    269319=back 
     
    272322 
    273323my %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, 
    278331); 
    279332 
     
    340393# mechanism. 
    341394sub 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    } 
    342402} 
    343403 
     
    352412The following functions have been implemented by any Clone object. 
    353413 
    354 =head2 HoneyClient::Agent::Driver->new($param => $value, ...) 
     414=head2 HoneyClient::Manager::VM::Clone->new($param => $value, ...) 
    355415 
    356416=over 4 
     
    358418Creates a new Clone object, which contains a hashtable 
    359419containing any of the supplied "param => value" arguments. 
    360 Upon creation, the Clone object clones the supplied master VM. 
    361420 
    362421I<Inputs>: 
     
    373432=begin testing 
    374433 
    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. 
     435my ($stub, $som, $URL); 
     436my $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. 
     441eval { 
     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. 
     487HoneyClient::Manager::VM->destroy(); 
     488sleep (1); 
     489 
     490# Report any failure found. 
     491if ($@) { 
     492    fail($@); 
     493
    381494 
    382495=end testing 
     
    420533    bless $self, $class; 
    421534 
    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(); 
    427538    } 
     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++; 
    428553 
    429554    # Finally, return the blessed object. 
     
    433558=pod 
    434559 
    435 =head2 $object->drive() 
     560=head2 $object->start() 
    436561 
    437562=over 4 
    438563 
    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. 
     564If not previously called, this method creates a new clone VM 
     565from the supplied master VM.  Furthermore, this method will power 
     566on the clone, and wait until the clone VM has fully booted and 
     567has an operational Agent daemon running on it. 
     568 
     569During this power on process, the name, MAC address, and  
     570IP address of the running clone are recorded in the object. 
     571 
     572I<Output>: The updated Clone B<$object>, containing state information 
     573from starting the clone VM.  Will croak if this operation fails. 
    446574 
    447575=back 
    448576 
    449 =begin testing 
    450  
     577# XXX: FINISH THIS 
     578#=begin testing 
     579
    451580# 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 testing 
     581#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 
    456585 
    457586=cut 
    458587 
    459 sub drive { 
    460     # Get the class name. 
    461     my $self = shift; 
     588sub 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    } 
    462599     
    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    } 
    469610} 
    470611 
     
    483624=back 
    484625 
    485 =begin testing 
    486  
     626#=begin testing 
     627
    487628# 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 testing 
     629#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 
    492633 
    493634=cut 
     
    568709=back 
    569710 
    570 =begin testing 
    571  
     711#=begin testing 
     712
    572713# 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 testing 
     714#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 
    577718 
    578719=cut 
     
    651792=back 
    652793 
    653 =begin testing 
    654  
     794#=begin testing 
     795
    655796# 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 testing 
     797#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 
    660801 
    661802=cut 
  • honeyclient/branches/exp/mbriggs-db/t/honeyclient_manager_vm.t

    r416 r596  
    99# =begin testing 
    1010{ 
     11# Make sure ExtUtils::MakeMaker loads. 
     12BEGIN { 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."); } 
     13require_ok('ExtUtils::MakeMaker'); 
     14can_ok('ExtUtils::MakeMaker', 'prompt'); 
     15use ExtUtils::MakeMaker qw(prompt); 
     16 
    1117# 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."); 
     18diag("About to run basic unit tests."); 
     19diag("Note: These tests *expect* VMware Server or VMware GSX to be installed and running on this system beforehand."); 
     20 
     21my $question; 
     22$question = prompt("# Do you want to run basic tests?", "yes"); 
     23if ($question !~ /^y.*/i) { 
     24    exit; 
     25
    1326 
    1427# Make sure Log::Log4perl loads 
     
    154167use Thread::Semaphore; 
    155168 
    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  
     169diag("About to run extended tests."); 
    160170# Generate a notice, to inform the tester that these tests are not 
    161171# exactly quick. 
    162 diag("Note: These unit tests will take *significant* time to complete (10-30 minutes)."); 
     172diag("Note: These extended tests will take *significant* time to complete (10-30 minutes)."); 
     173 
     174my $question = prompt("# Do you want to run extended tests?", "no"); 
     175if ($question !~ /^y.*/i) { 
     176    exit; 
     177
    163178} 
    164179 
     
    11591174    # this question, if need be. 
    11601175    if ($som->result == VM_EXECUTION_STATE_STUCK) { 
    1161         $som = $stub->answerVM(config => $cloneVM); 
     1176        $som = $stub->answerVM(config => $masterVM); 
    11621177    } 
    11631178 
  • honeyclient/branches/exp/mbriggs-db/t/honeyclient_manager_vm_clone.t

    r536 r596  
    4343use HoneyClient::Util::Config qw(getVar); 
    4444 
    45 # XXX: FIX THIS 
     45# Make sure HoneyClient::Util::SOAP loads. 
     46BEGIN { 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."); } 
     47require_ok('HoneyClient::Util::SOAP'); 
     48can_ok('HoneyClient::Util::SOAP', 'getClientHandle'); 
     49use HoneyClient::Util::SOAP qw(getClientHandle); 
     50 
     51# Make sure HoneyClient::Manager::VM loads. 
     52BEGIN { 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."); } 
     53require_ok('HoneyClient::Manager::VM'); 
     54use HoneyClient::Manager::VM; 
     55 
     56# Make sure VMware::VmPerl loads. 
     57BEGIN { 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."); } 
     58require_ok('VMware::VmPerl'); 
     59use VMware::VmPerl qw(VM_EXECUTION_STATE_ON VM_EXECUTION_STATE_OFF VM_EXECUTION_STATE_STUCK VM_EXECUTION_STATE_SUSPENDED); 
     60 
    4661# Make sure the module loads properly, with the exportable 
    4762# 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; 
     63BEGIN { 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."); } 
     64require_ok('HoneyClient::Manager::VM::Clone'); 
     65use HoneyClient::Manager::VM::Clone; 
    5666 
    5767# Suppress all logging messages, since we need clean output for unit testing. 
     
    6979can_ok('Storable', 'dclone'); 
    7080use Storable qw(dclone); 
     81 
     82# Make sure threads loads. 
     83BEGIN { use_ok('threads') or diag("Can't load threads package.  Check to make sure the package library is correctly listed within the path."); } 
     84require_ok('threads'); 
     85use threads; 
     86 
     87# Make sure threads::shared loads. 
     88BEGIN { 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."); } 
     89require_ok('threads::shared'); 
     90use threads::shared; 
     91 
     92# Make sure File::Basename loads. 
     93BEGIN { 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."); } 
     94require_ok('File::Basename'); 
     95can_ok('File::Basename', 'dirname'); 
     96can_ok('File::Basename', 'basename'); 
     97use File::Basename qw(dirname basename); 
    7198} 
    7299 
     
    75102# =begin testing 
    76103{ 
    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
     105my ($stub, $som, $URL); 
     106my $testVM = $ENV{PWD} . "/" . getVar(name      => "test_vm_config", 
     107                                      namespace => "HoneyClient::Manager::VM::Test"); 
    81108 
    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. 
     111eval { 
     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. 
     157HoneyClient::Manager::VM->destroy(); 
     158sleep (1); 
     159 
     160# Report any failure found. 
     161if ($@) { 
     162    fail($@); 
    83163} 
    84  
    85  
    86  
    87 # =begin testing 
    88 { 
    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 testing 
    97 { 
    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 testing 
    106 { 
    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 testing 
    115 { 
    116 # Create a g