[Bps-public-commit] r13614 - in TAP-Harness-Remote-EC2: lib/TAP/Harness/Remote

alexmv at bestpractical.com alexmv at bestpractical.com
Thu Jun 26 15:06:07 EDT 2008


Author: alexmv
Date: Thu Jun 26 15:05:46 2008
New Revision: 13614

Modified:
   TAP-Harness-Remote-EC2/   (props changed)
   TAP-Harness-Remote-EC2/Makefile.PL
   TAP-Harness-Remote-EC2/lib/TAP/Harness/Remote/EC2.pm

Log:
 r33500 at kohr-ah:  chmrr | 2008-06-26 15:05:18 -0400
  * Ability to auto-start instances


Modified: TAP-Harness-Remote-EC2/Makefile.PL
==============================================================================
--- TAP-Harness-Remote-EC2/Makefile.PL	(original)
+++ TAP-Harness-Remote-EC2/Makefile.PL	Thu Jun 26 15:05:46 2008
@@ -7,7 +7,7 @@
 license('perl');
 requires('Test::More');
 requires('TAP::Harness' => 3.04);
-requires('TAP::Harness::Remote');
+requires('TAP::Harness::Remote' => 0.03);
 requires('Net::Amazon::EC2');
 auto_install();
 &WriteAll;

Modified: TAP-Harness-Remote-EC2/lib/TAP/Harness/Remote/EC2.pm
==============================================================================
--- TAP-Harness-Remote-EC2/lib/TAP/Harness/Remote/EC2.pm	(original)
+++ TAP-Harness-Remote-EC2/lib/TAP/Harness/Remote/EC2.pm	Thu Jun 26 15:05:46 2008
@@ -1,6 +1,6 @@
 package TAP::Harness::Remote::EC2;
 
-our $VERSION = '0.01';
+our $VERSION = '0.02';
 
 use warnings;
 use strict;
@@ -27,10 +27,7 @@
 
 Configuration is much the same as L<TAP::Harness::Remote>, except the
 configuration file lives in C</.remote_test_ec2> -- see
-L</"CONFIGURATION AND ENVIRONMENT">.  Note the
-L<TAP::Harness::Remote::EC2> does not, at current, start EC2 hosts
-itself, nor differentiate in any way between running EC2 hosts; it
-attempts to connect and run tests on all currently running EC2 hosts.
+L</"CONFIGURATION AND ENVIRONMENT">.
 
 =head1 METHODS
 
@@ -47,7 +44,7 @@
     $self->SUPER::load_remote_config;
     warn
         "Useless 'host' configuration parameter set for TAP::Harness::Remote::EC2\n"
-        if grep {defined} @{$self->remote_config("host")};
+        if grep {defined} @{ $self->remote_config("host") };
     delete $self->{remote_config}{host};
 
     die "Configuration failed to include required 'access_key' parameter\n"
@@ -57,22 +54,81 @@
         "Configuration failed to include required 'secret_access_key' parameter\n"
         unless $self->remote_config("secret_access_key");
 
+    my $ami = $self->remote_config("ami");
+    warn "No value set for 'ami', assuming you mean all running instances\n"
+        unless defined $ami;
+
     my $ec2 = Net::Amazon::EC2->new(
         AWSAccessKeyId  => $self->remote_config("access_key"),
         SecretAccessKey => $self->remote_config("secret_access_key"),
     );
 
-    my $running_instances = $ec2->describe_instances;
+    my @hosts = $self->hosts( $ec2 => qr/running|pending/ );
+    my $run = $self->remote_config("instances") || 1;
+    my $need = $run - @hosts;
+    if ( $need > 0 ) {
+        die "Need to run $need new instances, but no AMI specified!\n"
+            unless $ami;
+
+        warn "Starting $need new instances of AMI $ami\n";
+        my $reservation = $ec2->run_instances(
+            ImageId      => $ami,
+            MinCount     => $need,
+            MaxCount     => $need,
+            InstanceType => $self->remote_config("instance_type")
+                || "m1.xlarge",
+        );
+        die join( "", map { $_->message } @{ $reservation->errors } )
+            . "\n"
+            if $reservation->isa("Net::Amazon::EC2::Errors");
+    }
 
-    my @hosts = map { $_->dns_name }
-        grep { $_->instance_state->name eq "running" }
-        map { @{ $_->instances_set } } @{$running_instances};
+    # Wait for starting instances
+    $self->wait_pending( $ec2 );
 
-    die "No EC2 hosts active\n" unless @hosts;
-    $self->{remote_config}{host} = \@hosts;
+    $self->{remote_config}{host}
+        = [ map { $_->dns_name } $self->hosts( $ec2 ) ];
     return $self;
 }
 
+=head2 hosts EC2, TYPE
+
+Limi
+
+=cut
+
+sub hosts {
+    my $self = shift;
+    my ( $ec2, $test ) = @_;
+    my $ami = $self->remote_config("ami");
+    $test ||= 'running';
+    $test = qr/$test/ unless ref $test;
+
+    my $running_instances = $ec2->describe_instances;
+    return grep { defined $ami ? ( $_->image_id eq $ami ) : 1 }
+        grep { $_->instance_state->name =~ $test }
+        map { @{ $_->instances_set } } @{$running_instances};
+}
+
+sub wait_pending {
+    my $self = shift;
+    my ( $ec2 ) = @_;
+    my @hosts = $self->hosts( $ec2 => "pending" );
+    return unless @hosts;
+
+    my $delay = 60;
+    while (@hosts) {
+        warn "Waiting for @{[@hosts + 0]} starting instances..\n";
+        sleep $delay;
+        $delay = 20;
+        @hosts = $self->hosts( $ec2 => "pending" );
+    }
+
+    # Even after they report as "started," they still need time to
+    # start up sshd, etc.
+    sleep 30;
+}
+
 =head1 CONFIGURATION AND ENVIRONMENT
 
 The configuration is stored in F<~/.remote_test_ec2>, and is mostly
@@ -93,11 +149,28 @@
 EC2 hosts.  You can find your access keys at
 L<https://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key>
 
+=item *
+
+There is an optional C<ami> parameter, which limits which AMIs will be
+used to run tests; it also lets the harness start the instances if
+there are not enough running.
+
+=item *
+
+There is an optional C<instances> parameter, which specifies the
+number of AMI instances to run tests on.  Defaults to one.
+
+=item *
+
+There is an optional C<instance_type> parameter, which controls the
+type of instances to create; possible arguments are C<m1.small>,
+C<m1.large>, and C<m1.xlarge>.  The default is C<m1.xlarge>.
+
 =back
 
 =head1 DEPENDENCIES
 
-L<Net::Amazon::EC2>
+L<Net::Amazon::EC2>, L<TAP::Harness::Remote>
 
 =head1 BUGS AND LIMITATIONS
 
@@ -105,9 +178,6 @@
 B<extremely> slow (about 4x slower than a clean, optimized build).  We
 thus strongly suggest you compile your own.
 
-In the future, L<TAP::Harness::Remote::EC2> may provide configuration
-options so that it can start and stop testing instances on demand.
-
 =head1 AUTHOR
 
 Alex Vandiver  C<< <alexmv at bestpractical.com> >>



More information about the Bps-public-commit mailing list