Paws XIV (The Sun King)
Well carrying on with my quest to clean up the Paws S3 code I decided while I am waiting for my last batch of changes to be reviewed I decided to review some of the 'TODO' tests.
TODO passed: 6364, 6370, 7896, 10045, 10052, 10137
First a 'TODO' test is a stubbed in test that will most likely fail and if it does it will not effect the final Pass/Fail of test case. It is basically one of these
The first one I am going to play with is 's3-get-bucket-location.response.test.yml which looks like this
--- todo: 'S3 is not stable' call: GetBucketLocation service: S3 tests: - expected: EU op: eq path: LocationConstraint
So the first thing I did was chop off that 'todo' line;
--- --todo: 'S3 is not stable' call: GetBucketLocation service: S3 …
and then check the content in the '3-get-bucket-location.response';
--- content: | <?xml version="1.0" encoding="UTF-8"?> <LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">EU</LocationConstraint> headers: [] status: 200
and that looks ok and on a test run I get the fail
ok 10045 - Call S3->GetBucketLocation from t/10_responses/s3-get-bucket-location.response Use of uninitialized value $got in string eq at (eval in cmp_ok) t/10_responses.t line 136. not ok 10046 - Got LocationConstraint eq EU from result# Failed test 'Got LocationConstraint eq EU from result'
# at t/10_responses.t line 136.
# got: undef
# expected: 'EU'
and one less on my todo pass
TODO passed: 6364, 6370, 7896, 10052, 10137
Looking to see where things have gone awry I had a look at the generated 'Paws::S3::GetBucketLocationOutput' class;
package Paws::S3::GetBucketLocationOutput;
use Moose;
has LocationConstraint => (is => 'ro', isa => 'Str');
has _request_id => (is => 'ro', isa => 'Str');
1;
and that links up with the test, so I think botocore it correct it must be in the 'Paws::Net::RestXMLResponse' class someplace
I know I am getting the correct response as I did a Dump of that in the 'process' sub and got;
process response=$VAR1 = bless( {
'headers' => {},
'content' => '<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">EU</LocationConstraint>
',
'status' => '200'
}, 'Paws::Net::APIResponse' );
and I will have to look a little deeper and I should look in the 'unserialize_response' sub as that is where the XML is converted into a hash and what I am going to look at is what goes in there;
sub unserialize_response {
my ($self, $data) = @_;
warn(“XML in=”.Dumper($data));
return {} if (not defined $data or $data eq '');
my $xml = XML::Simple->new(
ForceArray => qr/^(?:item|Errors)/i,
KeyAttr => '',
SuppressEmpty => undef,
);
return $xml->parse_string($data);
}
and I get
XML in=$VAR1 = '<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">EU</LocationConstraint>';
so the data are coming in correctly could it be the parser not working?
} else {
$unserialized_struct = eval { $self->unserialize_response( $content ) };
++ warn("JPS response_to_object unserialized_struct=".Dumper($unserialized_struct));
if ($@){
and I get
response_to_object unserialized_struct=$VAR1 = {
'xmlns' => 'http://s3.amazonaws.com/doc/2006-03-01/',
'content' => 'EU'
};
hmm correct but there is no way that can be linked back to the 'LocationConstraint' attribute in my generated class. I think I will have to wrap it somehow or parse it in another way as I want to see in
'content' => {<LocationConstraint>'EU'</LocationConstraint>},
I am not an expert of XML::Simple but I think if I do this
my $xml = XML::Simple->new(
ForceArray => qr/^(?:item|Errors)/i,
SuppressEmpty => undef,
ForceContent => 1,
ContentKey => 'LocationConstraint',
KeyAttr => ''
);
Add in the ' ForceContent => 1' and 'ContentKey => 'LocationConstraint' options to the parser and it will work but that will kill any other XML parseing as it wants the tag defined byt that ' ContentKey' option otherwise the parse will fail.
Looks like I have to figure out some way to get a flag in there to help me out? Perhaps a new trait?
Lets have a look in the botocore json to see what I can work with, in this case I want to look at is the '"GetBucketLocationOutput" stuct
"GetBucketLocationOutput":{
"type":"structure",
"members":{
"LocationConstraint":{
"shape":"BucketLocationConstraint",
"documentation":"<p/>"
}
}
},
Hmm that does not look correct as it is taking a shape as a ' BucketLocationConstraint' which to me means it trying to limit some input not output? Anyway that constraint looks like this;
"BucketLocationConstraint":{
"type":"string",
"enum":[
"EU",
"eu-west-1",
"us-west-1",
"us-west-2",
"ap-south-1",
"ap-southeast-1",
"ap-southeast-2",
"ap-northeast-1",
"sa-east-1",
"cn-north-1",
"eu-central-1"
]
},
I could just change the ' LocationConstraint' but I do not want to change the boto code more that I have to, so there must be a better way?
Anyway I can see why the left this one out.
Leave a comment