Paws XXXI (Digging up more dirt)

I ending up in my last post with a test that was running but most of the tests where failing.

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
…
ok 11 - Got method eq PUT from result
I had a look at the request object I was getting back

 bless( {
                 'url' => 'https://s3.fake_region.amazonaws.com/oneoffpaws',
                 'method' => 'PUT',
                 'content' => '<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><LocationConstraint>us-east-1</LocationConstraint></CreateBucketConfiguration>',
                 'uri' => '/oneoffpaws',
                 'parameters' => {
                                   'Bucket' => 'oneoffpaws',
                                   'GrantWriteACP' => 'emailAddress="write_acp_1@amazon.com", emailAddress="write_acp_2@amazon.com"',
                                   'ACL' => 'private',
...
               }, 'Paws::Net::S3APIRequest' );
and could see what was going on. Both 'content' and 'method' where where attributes where the other bits I was looking for like 'Bucket' = 'oneoffpaws' where key value pairs found in other attributes as in this case parameters.

The root cause is that test case t/10_response.t was designed to test classes that had embeded classes. Time to have a look at the guts of my new test runner t/09_request.t as major changes are required.

First I changed my test case a little;


- expected: oneoffpaws
op: eq
path: parameters
++ key: Bucket

I added a key to search on.

In then end I had to drop all of the code from t/10_resopnse that was handling embedded objects and just now have very simple code that either tests for the value of an attribute or the value of a key on an attribute;


eval {

if ( exists( $t->{key} ) ) {
my $hash = $res->$path;
$got = $hash->{ $t->{key} }
if ( exists( $hash->{ $t->{key} } ) );
$path = "Param->key: " . $t->{key};
}
else {
$got = $res->$path;
}
};
if ($@) {
my $message = $@;
chomp $message;
ok( 0, "Exception accessing $t->{path}: $message" );
}
if ( not defined $got and not defined $t->{expected} ) {
ok( 1, "Got undef on $path from result" );
}
else {
cmp_ok( $got, $t->{op}, $t->{expected},
"Got $path $t->{op} from result" );
}


and now my tests all pass!!

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
ok 3 - Got parameters eq dev.cargotel.paws.new from result
ok 4 - Got headers eq private from result
ok 5 - Got headers eq emailAddress="full_control_1@amazon.com", emailAddress="full_control_2@amazon.com" from result
ok 6 - Got headers eq emailAddress="read_1@amazon.com", emailAddress="read_2@amazon.com" from result
ok 7 - Got headers eq emailAddress="read_acp_1@amazon.com", emailAddress="read_acp_2@amazon.com" from result
ok 8 - Got headers eq emailAddress="write_1@amazon.com", emailAddress="write_2@amazon.com" from result
ok 9 - Got headers eq emailAddress="write_acp_1@amazon.com", emailAddress="write_acp_2@amazon.com" from result
ok 10 - Got headers eq 1 from result
ok 11 - Got method eq PUT from result
1..11

Now on to something else.

But wait I started to have other problems once I got a little further along writing tests. I was getting random fails like this


not ok 22 Got url eq from result;

got: 'https://s3.fake_region.amazonaws.com/oneoffpaws/one/to/delete
/image.jpg?versionId=MyObjectVersionId&retention='
expected: 'https://s3.fake_region.amazonaws.com/oneoffpaws/one/to/delete
/image.jpg?retention=&versionId=MyObjectVersionId
'


and some times this

not ok 1 Got content eq from result


got” '<RestoreRequest xmlns="http://s3.amazonaws.com/doc/2006-03-01/" >
<Days>2</Days>
<GlacierJobParameters>
<Tier>Standard</Tier>
</GlacierJobParameters>
</RestoreRequest>'

expected: '<RestoreRequest xmlns="http://s3.amazonaws.com/doc/2006-03-01/" >
<GlacierJobParameters>
<Tier>Standard</Tier>
</GlacierJobParameters>
<Days>2</Days>
</RestoreRequest>
'


Hmm!! test results not matching up.

All the parts are there just the order is incorrect.

The XML side of things was easy enough to fix up I just added some code to the RestsXmlCaller.pm to keep the outgoing XML in the same order. Useless sorting as AWS does not care but it necessary to make my test pass;


sub _to_xml_body {
my ($self, $call) = @_;
my $xml = '';
-- foreach my $attribute ($call->meta->get_all_attributes) {
++ foreach my $attribute (sort { $a->name cmp $b->name } $call->meta->get_all_attributes) {

Now the URL part was a little more tricky to fix as I had no way to sort the output of the request URI and URL params. I could just ignore them but with all the trouble I have had getting them to work in the first place I think a test is required.

In the end I decided to simply check for the existence of a key~pairs in the URL and URI strings. Thus given the URL from above;


https://s3.fake_region.amazonaws.com/oneoffpaws/one/to/delete/image.jpg?versionId=MyObjectVersionId&retention=

I break that into three tests

- expected: https://s3.fake_region.amazonaws.com/oneoffpaws/one/to/delete/image.jpg?
path: url
- expected: retention=
path: url
- expected: versionId=MyObjectVersionId
path: url

and just for good measure I added in three more tests that check just the URI;

- expected: /oneoffpaws/one/to/delete/image.jpg?
path: uri
- expected: retention=
path: uri
- expected: versionId=MyObjectVersionId
path: uri

I am not going to bother to lengthen this blog by sticking in all of the code for the above the as it is very basic the test utilizing the index function like this

ok( index( $url, $t->{expected} ) != -1,
"Have " . $t->{expected} . " in the URL"
);

With these two little fixes a change to the seven other tests I create before I fixed it I was getting consistent full test passes

So with that rounded up I just have to create some 80+ tests.


xu3flkro1ot21.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