Paws XXX (Three of a kind)

Goodness Paws 30 and I am at least code compete as far as running through all of the different action found on S3. Now that leads me to a very important part.

I now have to do a little bit of back peddling and come up with a test suite for all the now fixed S3 actions. 90% of the bugs and fixes I have done so far on S3 have been for requests to the server not checking responses form the server.

Following on with this it makes sense that I test how things are sent to the server as well. I had a peek about in the test suite and except for a few of the basic actions there are no tests on request calls.

Going forward Paws will need this to ensure that any change to boto or the AWS API that may cause a problem for paws will be caught early. Also for anyone who follows on with my work it is good to know there is a full test suite that works, even if it is mocked data.

So far I know that all of the S3 actions work as I have my own real test script that I can compare to the results to. So I can say with confidence that any requests tests I come up will work given valid parameters and permissions.

But where to start!! We do have the t/10_response.t to have a look at and use a base but what to call the test case?

Unfortunately I am somewhat limited in my choices for a name as those that have gone before me choose a simple sequential naming convention so there are no functions 'blocks' of test case numbers I can use.

Oh well I finally came up with t/09_request.t.

I took a good look at 10_response.t and I quickly discovered I could work with it. I could use the same testing convention with test data in one 'YML' file and tests in another. This time rather that the expected results in the data file I just use the data file as the parameter hash of my function call.

This greatly simplifies my test case as I can drop all the code out of 09_reqest that was used to generate and insert fudged data into the responses.

Lucky I can use the same style of 'test' YML files or at least very close to what is used in the 10 test case.

The fist thing I had to do was change this call in 'sub test_file'


    my $service = $aws->service($test->service,
      region => 'fake_region',
      caller => FileCaller->new(
        response_file => $file,
++      request_only  => 1,
      )
    );

I added in a new param to the FileCaller and I handle it like this


sub do_call {
my ( $self, $service, $call_object ) = @_;
my $response;

if ( $self->request_only ) {
return $service->prepare_request_for_call($call_object);
}
else {

my $response = $self->_file_response;


I just check for the param and if present I just call the prepare_request_for_call' sub and return the 'request' object rather than the 'response' object.

So now when I make my call it will be routed though the above and I will have a nice 'request' object I can play with.

Now lets try a test. Strating with the 'CreateBucket' action

The API has the following as the request call;

PUT / HTTP/1.1 Host: Bucket.s3.amazonaws.com x-amz-acl: ACL x-amz-grant-full-control: GrantFullControl x-amz-grant-read: GrantRead x-amz-grant-read-acp: GrantReadACP x-amz-grant-write: GrantWrite x-amz-grant-write-acp: GrantWriteACP x-amz-bucket-object-lock-enabled: ObjectLockEnabledForBucket <?xml version="1.0" encoding="UTF-8"?> <CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LocationConstraint>string</LocationConstraint> </CreateBucketConfiguration>

So that is what I should test against. All I need to do is add in the request params in this file 's3-create-bucket.request' as some YML


---
Bucket: oneoffpaws
CreateBucketConfiguration: us-east-1
ACL: private
GrantFullControl: emailAddress="full_control_1@amazon.com", emailAddress="full_control_2@amazon.com"
GrantRead: emailAddress="read_1@amazon.com", emailAddress="read_2@amazon.com"
GrantReadACP: emailAddress="read_acp_1@amazon.com", emailAddress="read_acp_2@amazon.com"
GrantWrite: emailAddress="write_1@amazon.com", emailAddress="write_2@amazon.com"
GrantWriteACP: emailAddress="write_acp_1@amazon.com", emailAddress="write_acp_2@amazon.com"
ObjectLockEnabledForBucket: 1

and some tests to go into the s3-create-bucket.request.test.yml file


---
call: CreateBucket
service: S3
tests:
  - expected: <CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><LocationConstraint>us-east-1</LocationConstraint></CreateBucketConfiguration>
    op: eq
    path: content
  - expected: dev.cargotel.paws.new
    op: eq
    path: parameters
  - expected: private
    op: eq
    key: x-amz-acl
  - expected: emailAddress="full_control_1@amazon.com", emailAddress="full_control_2@amazon.com"
    op: eq
    key: x-amz-grant-full-control
…
The same style again as found in the t/10_ test.

In 09_requests I now just do this


       my $passed = lives_ok {
            $res = $service->$call_method( %{$opts} );
        }
        "Call " . $test->service . '->' . $test->method . " from $file";

if ( not $passed or $TODO ) {
ok( 0,
"Can't test method access because something went horribly wrong in the call to $call_method"
);
next;
}


and pass my params directly into the call to the action.

On my first run I got


 died: Can't use string ("us-east-1") as a HASH ref while "strict refs" in use at /home/scolesj/aws-sdk-perl/auto-lib/Paws.pm line 136.
Which I eventuality found the problem in my data file;

this;


CreateBucketConfiguration: us-east-1
parses to a string. So to get this work I net the correct hash param like this

CreateBucketConfiguration: 
   LocationConstraint: us-east-1
Should of know that as I have done goddness knows how may posts on coercion over the past few years.

When I ran it again I got an error on the ' LocationConstraint' as that has to match up with the location entered when creating the service


  my $service = $aws->service($test->service,
      region => 'fake_region',

So I have to use that 'fake_region' in my test expected data.

I did a few changes and re-ran my test and got


ok 1 - Call S3->CreateBucket from /home/scolesj/aws-sdk-perl/t/09_requests/s3-create-bucket.request
ok 2 - Got content eq from result
not ok 3 - Got parameters eq dev.cargotel.paws.new from result
not ok 4 - Got headers eq private from result
not ok 5 - Got headers eq emailAddress="full_control_1@amazon.com", emailAddress="full_control_2@amazon.com" from result
not ok 6 - Got headers eq emailAddress="read_1@amazon.com", emailAddress="read_2@amazon.com" from result
not ok 7 - Got headers eq emailAddress="read_acp_1@amazon.com", emailAddress="read_acp_2@amazon.com" from result
not ok 8 - Got headers eq emailAddress="write_1@amazon.com", emailAddress="write_2@amazon.com" from result
not ok 9 - Got headers eq emailAddress="write_acp_1@amazon.com", emailAddress="write_acp_2@amazon.com" from result
not ok 10 - Got headers eq 1 from result
ok 11 - Got method eq PUT from result
1..11

well 3 out of 11 is not bad.

Will have to clean that up in my next post.


22082.jpg

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations