Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- Adds mechanism via which one can use to conditionally perform valid…
…ations,

  especially when the values generated by the test harness will be
invalid.
  The environment variable P6_AWS_TESTING should be set and code added
  any test in which this will be the case. See ::Action::CreateVolume
  for examples.

- Adds ::Action::CreateVolume. Tested to 1000 iterations.

+ Timings:
/ 125 => 1.670648337511545 / 625 => 15.213852025611384 / 1000 =>
20.561826197500295

+ Well, looks like it's time to come up for air.. and lo and BEHOLD!
  Amazon-AWS-EC2 has passed the 20kLOC mark!

  .:::.               .:::. ...:::::...:::::
 ,;'``;.   ,;;,      ,;'``;.'''``;;''''``;;'
 ''  ,[[',['  [n     ''  ,[['   .['     .['
 .c$$P'  $$    $$    .c$$P'   ,$$'    ,$$'
d88 _,oo,Y8,  ,8"d8bd88 _,oo, 888     888
MMMUP*"^^ "YmmP  ,M"MMMUP*"^^ MMM     MMM      LINES OF CODE!

This brings my Perl6 total to:

  .:::.  .::.   ::::::::   :.  .,,.   .::.
 ,;'``;.;'`';;, `;;``'';   ;;,;;'`';,;'`';;,
 ''  ,[['  .n[[  [[,_      [[[[, _,[[   .n[[
 .c$$P'   ``"$$$.`""*Ycc   $$ Y$$P"$$  ``"$$$.
d88 _,oo, ,,o888"__,od8"d8b88 ,,_,d8"  ,,o888"
MMMUP*"^^ YMMP"  MMP"   ,M"MM  "MP"    YMMP"   LINES OF CODE!

That's 235,193 lines of code over 15 projects and 13 months!

\o/ \o/ \o/
  • Loading branch information
Xliff committed Jul 15, 2019
1 parent a0c730d commit ce9ce3b
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 2 deletions.
11 changes: 11 additions & 0 deletions META6.json
Expand Up @@ -723,6 +723,17 @@

















Expand Down
160 changes: 160 additions & 0 deletions lib/Amazon/AWS/EC2/Action/CreateVolume.pm6
@@ -0,0 +1,160 @@
use v6.d;

use Method::Also;

use XML::Class;

use Amazon::AWS::Utils;

use Amazon::AWS::EC2::Types::TagSpecification;

use Amazon::AWS::EC2::Response::CreateVolumeResponse;

my %attributes;

class Amazon::AWS::EC2::Action::CreateVolume is export
does XML::Class[xml-element => 'CreateVolume']
{
also does Amazon::AWS::Roles::Eqv;

my $c = ::?CLASS.^name.split('::')[* - 1];

has Str $.AvailabilityZone is xml-element is xml-skip-null is rw;
has Bool $.DryRun is xml-element is xml-skip-null is rw;
has Bool $.Encrypted is xml-element is xml-skip-null is rw;
has Int $.Iops is xml-element is xml-skip-null is rw;
has Str $.KmsKeyId is xml-element is xml-skip-null is rw;
has Int $.Size is xml-element is xml-skip-null is rw;
has Str $.SnapshotId is xml-element is xml-skip-null is rw;
has TagSpecification @.TagSpecifications is xml-container('tagSpecificationSet') is xml-element('item', :over-ride) is xml-skip-null is rw;
has Str $.VolumeType is xml-element is xml-skip-null is rw; #= standard | io1 | gp2 | sc1 | st1

submethod BUILD (
:$availabilityZone,
:$dryRun,
:$encrypted,
:$iops,
:$kmsKeyId,
:$size,
:$snapshotId,
:@tagSpecifications,
:$volumeType,
# For deserialization purposes, only!
:$!AvailabilityZone = '',
:$!DryRun = False,
:$!Encrypted = False,
:$!Iops = 32000,
:$!KmsKeyId = '',
:$!Size = 0,
:$!SnapshotId = '',
:@!TagSpecifications,
:$!VolumeType = 'standard'
) {
$!DryRun = $dryRun if $dryRun;
$!Iops = $iops if $iops;
$!Size = $size if $size;

if @tagSpecifications {
@!TagSpecifications = do given @tagSpecifications {
when .all ~~ TagSpecification
{ $_ }

default {
die qq:to/DIE/
Invalid values passed to \@tagSpecifications. Elements must only consist of TagSpecifications, but also contains:
{ .grep( * !~~ TagSpecification ).map( *.^name ).join(', ') }
DIE

}
}
}

die "Iops value ({ $iops }) is invalid!"
unless %*ENV<P6_AWS_TESTING>.defined || $iops.defined && $!Iops ~~ 50..64000;

$!KmsKeyId = $kmsKeyId
if $kmsKeyId.defined && $kmsKeyId.trim.chars;
$!AvailabilityZone = $availabilityZone
if $availabilityZone.defined && $availabilityZone.trim.chars;
$!SnapshotId = $snapshotId
if $snapshotId.defined && $snapshotId.trim.chars;
$!VolumeType = $volumeType
if $volumeType.defined && $volumeType.trim.chars;

my $vtDieMsg;
$vtDieMsg = qq:to/DIE/ if $volumeType.defined && $volumeType.trim.chars;
VolumeType is set to an invalid value ({ $volumeType }). It must be one of the following:
{ %attributes<VolumeType|Table> }
DIE

die $vtDieMsg unless $!VolumeType.chars.not ||
$!VolumeType ~~ self.getValidVolumeTypes.any;

my $range = do given $!VolumeType {
when 'gp2' { 1..16384 }
when 'io1' { 4..16384 }
when 'st1' | 'sc1' { 500..16384 }
when 'standard' { 1.. 1024 }
};

my $sDieMsg = qq:to/DIE/;
Given size ({ $!Size }) is invalid for volume type { $!VolumeType }. Valid range is:
{ $range.min } - { $range.max }
DIE

die $sDieMsg unless %*ENV<P6_AWS_TESTING>.defined || $!Size.not || $!Size ~~ $range;

}

method run (:$raw)
is also<
do
execute
>
{
my @TagSpecArgs;
my $cnt = 1;
for @!TagSpecifications {
@TagSpecArgs.push: Pair.new("TagSpecification.{$cnt++}.{.key}", .value)
for .pairs;
}

# YYY - Other conditions for validity:
# AvailabilityZone - End User validation
# Size vs SnapshotId - End User validation

# @Args must be sorted by key name.
my @args;
@args.push: (AvailabilityZone => $!AvailabilityZone) if $!AvailabilityZone.chars;
@args.push: (DryRun => $!DryRun) if $!DryRun;
@args.push: (Encrypted => $!Encrypted) if $!Encrypted;
@args.push: (Iops => $!Iops) if $!Iops;
@args.push: (KmsKeyId => $!KmsKeyId) if $!KmsKeyId.chars;
@args.push: (Size => $!Size) if $!Size;
@args.push: (SnapshotId => $!SnapshotId) if $!SnapshotId.chars;
@args.append: @TagSpecArgs if @TagSpecArgs;
@args.push: (Version => '2016-11-15');
@args.push: (VolumeType => $!VolumeType);

# XXX - Add error handling to makeRequest!
my $xml = makeRequest(
"?Action={ $c }&{ @args.map({ "{.key}={.value}" }).join('&') }"
);

$raw ??
$xml
!!
::("Amazon::AWS::EC2::Response::{ $c }Response").from-xml($xml);
}

method getValidVolumeTypes {
%attributes<VolumeType|ValidValues>.Array;
}

}

BEGIN {
%attributes = getAttributeData(
Amazon::AWS::EC2::Action::CreateVolume
);
}
6 changes: 4 additions & 2 deletions lib/Amazon/AWS/EC2/TODO
Expand Up @@ -69,6 +69,7 @@
+ CreateSnapshot
+ DeleteSnapshot
+ DescribeVpcEndpoint
+ GetPasswordData

# Might need vpc: action permissions as well!
e CreateDefaultSubnet (Completed, but no valid response retrieved)
Expand All @@ -80,6 +81,7 @@
- CreateTags (Needs resource id)
- CreateCapacityReservation
- CreateNatGateway
- CreateVolume

# Should create corresponding Delete actions for all Create actions!

Expand Down Expand Up @@ -116,9 +118,9 @@
|| check = Fully Qualified Subroutine Name (routine to check attribute values)
pick = Fully Qualified Subroutine Name (routine to generate random attribute values for testing)
comp = Name of CompUnit (will provide check and pick routines. Equivalent to:

"pick=<compunit>::<pickSub>" and "check=<compunit>::<checkSub")
+ Write an ID validation routine.

- Write an ID validation routine.
+ Known Id prefixes:
eni - Elastic Network Interface
i - Instance
Expand Down

0 comments on commit ce9ce3b

Please sign in to comment.