# -*- tcl -*- # S3.test: tests for the S3 access package. # This file contains a collection of tests for the S3 # package. Sourcing this file into Tcl runs the tests and generates # output for errors. No output means no errors were found. # Copyright (c) 2006,2008 Darren New. All Rights Reserved. # Copyright (c) 2008 Andreas Kupries # (Boilerplate stuff (header, footer)) # All rights reserved. # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ devtools testutilities.tcl] testsNeedTcl 8.5 testsNeedTcltest 2.0 support { use uri/uri.tcl uri } testsNeed xml ; # aka TclXML, author Steve Ball, of Zveno (Australia) # Put your own keys into test-assets/aws-access-id, aws-secret-access_key # ------------------------------------------------------------------------- if {![file exists [localPath test-assets/aws-access-id]] || ![file exists [localPath test-assets/aws-secret-access-key]] } { if {[file exists [localPath test-assets/no-aws]]} { puts " Skipping the tests found in \"[file tail [info script]]\"" puts " AWS not configured by user choice." } else { puts " Aborting the tests found in \"[file tail [info script]]\"" puts " AWS configuration required, missing." puts " Place access id and secret key into the files" puts " - [localPath test-assets/aws-access-id], and" puts " - [localPath test-assets/aws-secret-access-key]" } return } # ------------------------------------------------------------------------- support { # Requires xml (TclXML) useLocal xsxp.tcl xsxp ;# Here we need (tcl)xml } testing { useLocal S3.tcl S3 } # ------------------------------------------------------------------------- # I normally leave BucketDeletion false, because Amazon gets cranky # if you delete a bucket and then try to recreate it any time soon. # This may clobber files starting with the characers "S3T". Don't # run it in a directory with such files you want. # Put your own keys in test-assets/test-S3.config. tcltest::customMatch S3err S3ErrorMatch tcltest::testConstraint BucketDeletion false tcltest::testConstraint REST true tcltest::testConstraint BucketIO true tcltest::testConstraint ItemIO true tcltest::testConstraint Put true tcltest::testConstraint Get true tcltest::testConstraint Acl true tcltest::testConstraint Head true tcltest::testConstraint Directory true tcltest::testConstraint Delete true tcltest::configure -verbose {body error pass skip start} tcltest::configure -debug 1 # Allow easy testing of S3-style errorCode returns. proc S3expectErr {code} { global errorCode set errorCode {} set x [catch $code result] return [concat $x $errorCode] } proc S3ErrorMatch {expected actual} { if {$expected eq [lrange $actual 0 [expr {[llength $expected]-1}]]} { return true } else { return false } } # Allow easy testing of background tasks. proc S3expectBackgroundREST {req} { # Might be done better, tho... set ::S3::afterResult {} set ::S3::afterRan 0 set y [after 1 {set ::S3::afterRan 1}] S3::REST $req vwait [dict get $req resultvar] set x [set [dict get $req resultvar]] after cancel $y #if {$::S3::afterResult eq "AFTER-FAILURE"} { #error "Background task never returned value" "" [after info $x] #} if {[string match "BGERROR*" $::S3::afterResult]} { error "BGError triggered: $::S3::afterResult" "" $::S3::afterResult } if {0 == $::S3::afterRan} { error "Concurrent events did not run" "" "S3 test afterRan" } return $x } proc S3expectBackground {code} { # Might be done better, tho... set ::S3::afterResult {} set ::S3::afterRan 0 set y [after 1 {set ::S3::afterRan 1}] set x [eval $code] after cancel $y #if {$::S3::afterResult eq "AFTER-FAILURE"} { #error "Background task never returned value" "" [after info $x] #} if {[string match "BGERROR*" $::S3::afterResult]} { error "BGError triggered: $::S3::afterResult" "" $::S3::afterResult } if {0 == $::S3::afterRan} { error "Concurrent events did not run" "" "S3 test afterRan" } return $x } proc bgerror {args} {set ::S3::afterResult [list "BGERROR" $args $::errorInfo]} # Allow easy incorporation of user's AccessID and SecretKey proc S3loadKeys {} { source [localPath test-assets test-S3.config] } namespace import ::tcltest::test proc CleanUpBuckets {{buckets 0}} { S3loadKeys set bucket [S3::SuggestBucket TclTestS3b] for {set i 0} {$i < 25} {incr i} { puts "Deleting $i of 25" for {set j 0} {$j < 10} {incr j} { set q [format %02d $i] set d [S3::REST \ [dict create verb DELETE resource /$bucket/thing/$q/$j]] S3::throwhttp $d } } S3::REST [dict create verb DELETE resource /$bucket/fred ] S3::REST [dict create verb DELETE resource /$bucket/barney ] S3::REST [dict create verb DELETE resource /$bucket/wilma ] S3::REST [dict create verb DELETE resource /$bucket/betty ] S3::REST [dict create verb DELETE resource /$bucket/cartman ] S3::REST [dict create verb DELETE resource /$bucket/cartoon/tweety ] S3::REST [dict create verb DELETE resource /$bucket/cartoon/sylvester ] S3::REST [dict create verb DELETE resource "/$bucket/cartoon/road runner" ] S3::REST [dict create verb DELETE \ resource "/$bucket/cartoon/wile e. coyote" ] if {$buckets} {S3::REST [dict create verb DELETE resource /$bucket]} } # CleanUpBuckets 0 ; exit # Test URL encoding test S3-1.10 {URL encoding no parameters} -body { S3::to_url /quotes/nelson {} } -result {/quotes/nelson} test S3-1.20 {URL encoding with parameters} -body { S3::to_url /quotes/nelson {alpha one beta two} } -result {/quotes/nelson?alpha=one&beta=two} test S3-1.30 {URL encoding with parameters and query} -body { S3::to_url /quotes/nelson?acl {alpha one beta two} } -result {/quotes/nelson?acl&alpha=one&beta=two} test S3-1.40 {URL with non-ASCII characters} -body { set funky "/xyzzy/zz+fun\(\)good?junk space" append funky "&and_utf-8\u2211Sigma\u5927Da" S3::encode_url $funky } -result {/xyzzy/zz%2bfun%28%29good%3fjunk%20space%26and_utf-8%e2%88%91Sigma%e5%a4%a7Da} test S3-1.50 {Check out content types A} -setup { tcltest::makeFile "This is just text" "S3junk.txt" } -body { S3::contenttype S3junk.txt } -cleanup { tcltest::removeFile "S3junk.txt" } -result "text/plain" test S3-1.60 {Check out content types A} -body { # May be unhappy under UNIX? S3::contenttype origT1.jpg } -result "image/jpeg" test S3-2.10 {Config no args} -body { array set x [S3::Configure] foreach key [lsort [array names x]] { puts $key ; puts $x($key) } } -cleanup {unset x} -output "-accesskeyid\n\n-bucket-prefix\nTclS3\n-default-acl\n\n-default-bucket\n\n-default-compare\nalways\n-default-separator\n/\n-reset\nfalse\n-retries\n3\n-secretaccesskey\n\n-service-access-point\ns3.amazonaws.com\n-slop-seconds\n3\n-use-tls\nfalse\n" test S3-2.20 {Config, one arg} -body { S3::Configure -bucket-prefix } -result {TclS3} test S3-2.30 {Config, set bucket prefix} -body { S3::Configure -bucket-prefix TclTestS3 S3::Configure -bucket-prefix } -result {TclTestS3} test S3-2.40 {Config, bad first argument} -body { S3expectErr {S3::Configure -xyzzy} } -result "1 S3 usage -xyzzy" -match S3err test S3-2.50 {Config, wrong number of pairs} -body { set ::errorCode {} S3::Configure -bucket-prefix TclTestS3 set x [catch {S3::Configure -bucket-prefix 1234 -use-tls}] set y [S3::Configure -bucket-prefix] return [concat $x [lrange $::errorCode 0 1] $y] } -result {1 S3 usage TclTestS3} -cleanup {unset x ; unset y} test S3-2.60 {Config, test reset} -body { S3::Configure -bucket-prefix XYZZY -reset true return [S3::Configure -bucket-prefix] } -result TclS3 test S3-2.70 {Suggest bucket name} -body { S3::Configure -accesskeyid 44CF9590006BF252F707 \ -secretaccesskey OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV set x [S3::SuggestBucket Bloop] return [concat [string match *Bloop* $x] \ [string match *44CF9590006BF252F707* $x] \ [string match *OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV* $x]] } -result {1 1 0} # Now test the stuff from the manual test S3-3.10 {First documentation example of AUTH} -body { S3::Configure -accesskeyid 44CF9590006BF252F707 \ -secretaccesskey OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV set verb put set resource /quotes/nelson set content-type text/html set headers { date "Thu, 17 Nov 2005 18:49:58 GMT" content-md5 c8fdb181845a4ca6b8fec737b3581d76 x-amz-meta-author foo@bar.com x-amz-magic abracadabra } set res [S3::authREST $verb $resource ${content-type} $headers] dict get $res authorization } -result {AWS 44CF9590006BF252F707:jZNOcbfWmD/A/f3hSvVzXZjM2HU=} test S3-3.20 {Second documentation example of AUTH} -body { S3::Configure -accesskeyid 44CF9590006BF252F707 \ -secretaccesskey OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV set verb GET set resource /quotes/nelson set headers { date XXXXXXX x-amz-magic abracadabra x-amz-date "Thu, 17 Nov 2005 18:49:58 GMT" } set res [S3::authREST $verb $resource "" $headers] dict get $res authorization } -result {AWS 44CF9590006BF252F707:5m+HAmc5JsrgyDelh9+a2dNrzN8=} test S3-4.10 {REST Blocking list of buckets} -constraints "BucketIO REST" \ -setup S3loadKeys -body { set req [dict create verb GET resource /] set res [S3::REST $req] return [list [lsort [dict keys $res]] [dict get $res httpstatus] \ [expr {0<[string length [dict get $res outbody]]}]] } -result {{httpmessage httpstatus outbody outheaders resource verb} 200 1} test S3-4.20 {REST Nonblocking list of buckets} -constraints "BucketIO REST" \ -setup S3loadKeys -body { set req [dict create verb GET resource / resultvar ::S3RES] set res [S3expectBackgroundREST $req] return [list [lsort [dict keys $res]] [dict get $res httpstatus] \ [expr {0<[string length [dict get $res outbody]]}]] } -result {{httpmessage httpstatus outbody outheaders resource resultvar verb} 200 1} test S3-4.30 {REST blocking create bucket} -constraints "BucketIO REST" \ -setup S3loadKeys -body { set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b headers {x-amz-acl public-read}] set res [S3::REST $req] return [dict get $res httpstatus] } -result 200 test S3-4.40 {REST get bucket acl} -constraints "BucketIO REST" \ -setup S3loadKeys -body { set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb GET resource /$b rtype acl] set res [S3::REST $req] set lookfor {http://acs.amazonaws.com/groups/global/AllUsersREAD} set found [expr {-1 != [string first $lookfor $res]}] return [list $found [dict get $res httpstatus]] } -result "1 200" test S3-4.50 {REST blocking put,get,compare contents} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "This is a test. This is only a test.\nHad this been a real emergency, you would be dead.\n" set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t1.txt inbody $body \ headers {x-amz-acl public-read}] set res [S3::REST $req] set r1 [dict get $res httpstatus] set req [dict create verb GET resource /$b/t1.txt rtype acl] set res [S3::REST $req] set lookfor {http://acs.amazonaws.com/groups/global/AllUsersREAD} set r2 [expr {-1 != [string first $lookfor $res]}] set req [dict create verb GET resource /$b/t1.txt] set res [S3::REST $req] set r3 [string compare $body [dict get $res outbody]] return [list $r1 $r2 $r3] } -result "200 1 0" test S3-4.60 {REST nonblocking put,get,compare contents} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "This is a test. This is only a test.\nHad this been a real emergency, you would be dead.\n" set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t1.txt inbody $body \ headers {x-amz-acl public-read} resultvar ::S3REST] set res [S3expectBackgroundREST $req] set r1 [dict get $res httpstatus] set req [dict create verb GET resource /$b/t1.txt rtype acl resultvar ::S3REST] set res [S3expectBackgroundREST $req] set lookfor {http://acs.amazonaws.com/groups/global/AllUsersREAD} set r2 [expr {-1 != [string first $lookfor $res]}] set req [dict create verb GET resource /$b/t1.txt resultvar ::S3REST] set res [S3expectBackgroundREST $req] set r3 [string compare $body [dict get $res outbody]] return [list $r1 $r2 $r3] } -result "200 1 0" test S3-4.70 {REST blocking put,delete} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "This is a test. This is only a test.\nHad this been a real emergency, you would be dead.\n" set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t1.txt inbody $body] set res [S3::REST $req] set r1 [dict get $res httpstatus] set req [dict create verb DELETE resource /$b/t1.txt] set res [S3::REST $req] set r2 [dict get $res httpstatus] return [list $r1 $r2] } -result "200 204" ; # Delete returns "no content" test S3-4.80 {REST nonblocking put,delete} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "This is a test. This is only a test.\nHad this been a real emergency, you would be dead.\n" set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t1.txt inbody $body \ resultvar ::S3RES] set res [S3expectBackgroundREST $req] set r1 [dict get $res httpstatus] set req [dict create verb DELETE resource /$b/t1.txt resultvar ::S3RES] set res [S3expectBackgroundREST $req] set r2 [dict get $res httpstatus] return [list $r1 $r2] } -result "200 204" ; # Delete returns "no content" test S3-4.90 {REST blocking put,head,delete} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "This is a test. This is only a test.\nHad this been a real emergency, you would be dead.\n" set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t1.txt inbody $body] set res [S3::REST $req] set r1 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t1.txt] set res [S3::REST $req] set r2 [dict get $res httpstatus] set r3 [string length [dict get $res outbody]] set req [dict create verb DELETE resource /$b/t1.txt] set res [S3::REST $req] set r4 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t1.txt] set res [S3::REST $req] set r5 [dict get $res httpstatus] return [list $r1 $r2 $r3 $r4 $r5] } -result "200 200 0 204 404" test S3-4.100 {REST blocking put,head,delete from big body} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "0123456789" set body [string repeat $body 50000] ; # Make body 500,000 bytes. set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t1.txt inbody $body] set res [S3::REST $req] set r1 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t1.txt] set res [S3::REST $req] set r2 [dict get $res httpstatus] set r3 [string length [dict get $res outbody]] set r4 [dict get $res outheaders content-length] set req [dict create verb DELETE resource /$b/t1.txt] set res [S3::REST $req] set r5 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t1.txt] set res [S3::REST $req] set r6 [dict get $res httpstatus] return [list $r1 $r2 $r3 $r4 $r5 $r6] } -result "200 200 0 500000 204 404" test S3-4.110 {REST nonblocking put,head,delete from big body} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "0123456789" set body [string repeat $body 50000] ; # Make body 500,000 bytes. set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t2.txt inbody $body resultvar ::S3RES] set res [S3expectBackgroundREST $req] set r1 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t2.txt] set res [S3::REST $req] set r2 [dict get $res httpstatus] set r3 [string length [dict get $res outbody]] set r4 [dict get $res outheaders content-length] set req [dict create verb DELETE resource /$b/t2.txt] set res [S3::REST $req] set r5 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t2.txt] set res [S3::REST $req] set r6 [dict get $res httpstatus] return [list $r1 $r2 $r3 $r4 $r5 $r6] } -result "200 200 0 500000 204 404" test S3-4.120 {REST nonblocking put,head,delete from big file} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "0123456789" set body [string repeat $body 50000] ; # Make body 500,000 bytes. tcltest::makeFile "XXX" S3Tone.txt set x [open S3Tone.txt w] ; puts -nonewline $x $body ; close $x set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t3.txt infile S3Tone.txt resultvar ::S3RES] set res [S3expectBackgroundREST $req] set r1 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t3.txt] set res [S3::REST $req] set r2 [dict get $res httpstatus] set r3 [string length [dict get $res outbody]] set r4 [dict get $res outheaders content-length] set req [dict create verb DELETE resource /$b/t3.txt] set res [S3::REST $req] set r5 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t3.txt] set res [S3::REST $req] set r6 [dict get $res httpstatus] tcltest::removeFile S3Tone.txt return [list $r1 $r2 $r3 $r4 $r5 $r6] } -result "200 200 0 500000 204 404" test S3-4.130 {REST blocking put,head,delete from big file} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "0123456789" set body [string repeat $body 50000] ; # Make body 500,000 bytes. tcltest::makeFile "XXX" S3Tone.txt set x [open S3Tone.txt w] ; puts -nonewline $x $body ; close $x set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t3.txt infile S3Tone.txt] set res [S3::REST $req] set r1 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t3.txt] set res [S3::REST $req] set r2 [dict get $res httpstatus] set r3 [string length [dict get $res outbody]] set r4 [dict get $res outheaders content-length] set req [dict create verb DELETE resource /$b/t3.txt] set res [S3::REST $req] set r5 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t3.txt] set res [S3::REST $req] set r6 [dict get $res httpstatus] tcltest::removeFile S3Tone.txt return [list $r1 $r2 $r3 $r4 $r5 $r6] } -result "200 200 0 500000 204 404" test S3-4.140 {REST nonblocking put,get,delete into file} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "0123456789" set body [string repeat $body 50000] ; # Make body 500,000 bytes. set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t5.txt inbody $body resultvar ::S3RES] set res [S3expectBackgroundREST $req] set r1 [dict get $res httpstatus] tcltest::makeFile "blah" S3Ttwo.txt set x [open S3Ttwo.txt w] ; fconfigure $x -translation binary -encoding binary set req [dict create verb GET resource /$b/t5.txt outchan $x] set res [S3::REST $req] close $x set r2 [dict get $res httpstatus] set r3 [file size S3Ttwo.txt] tcltest::removeFile S3Ttwo.txt set req [dict create verb DELETE resource /$b/t3.txt] set res [S3::REST $req] set r4 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t3.txt] set res [S3::REST $req] set r5 [dict get $res httpstatus] return [list $r1 $r2 $r3 $r4 $r5] } -result "200 200 500000 204 404" test S3-4.150 {REST blocking put,get,delete into file} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "0123456789" set body [string repeat $body 50000] ; # Make body 500,000 bytes. set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b/t5.txt inbody $body] set res [S3::REST $req] set r1 [dict get $res httpstatus] tcltest::makeFile "blah" S3Ttwo.txt set x [open S3Ttwo.txt w] ; fconfigure $x -translation binary -encoding binary set req [dict create verb GET resource /$b/t5.txt outchan $x] set res [S3::REST $req] close $x set r2 [dict get $res httpstatus] set r3 [file size S3Ttwo.txt] tcltest::removeFile S3Ttwo.txt set req [dict create verb DELETE resource /$b/t5.txt] set res [S3::REST $req] set r4 [dict get $res httpstatus] set req [dict create verb HEAD resource /$b/t5.txt] set res [S3::REST $req] set r5 [dict get $res httpstatus] return [list $r1 $r2 $r3 $r4 $r5] } -result "200 200 500000 204 404" test S3-4.160 {REST blocking put,get,delete of file with encoded name} \ -constraints "ItemIO REST" \ -setup S3loadKeys -body { set body "0123456789" set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set funky "/$b/zz+fun\(\)good?junk space" append funky "&and_utf-8\u2211Sigma\u5927Da" set req [dict create verb PUT resource $funky inbody $body] set res [S3::REST $req] set r1 [dict get $res httpstatus] set req [dict create verb GET resource $funky] set res [S3::REST $req] set r2 [dict get $res httpstatus] set req [dict create verb DELETE resource $funky] set res [S3::REST $req] set r3 [dict get $res httpstatus] set req [dict create verb HEAD resource $funky] set res [S3::REST $req] set r4 [dict get $res httpstatus] return [list $r1 $r2 $r3 $r4] } -result "200 200 204 404" test S3-4.170 {REST delete bucket} \ -constraints "BucketDeletion REST" \ -setup S3loadKeys -body { # Bucket ought to be empty by now. # Of course, if a delete fails for some reason... set b "TclTestS3.REST.[S3::Configure -accesskeyid]" set req [dict create verb PUT resource /$b headers {x-amz-acl public-read}] set res [S3::REST $req] set r1 [dict get $res httpstatus] after 5000 ; # Give AWS a chance to remember it. set req [dict create verb DELETE resource /$b] set res [S3::REST $req] after 5000 ; # Give AWS a chance to remember it. set r2 [dict get $res httpstatus] set req [dict create verb GET resource /$b] set res [S3::REST $req] set r3 [dict get $res httpstatus] return [list $r1 $r2 $r3] } -result "200 204 404" test S3-10.10 {ListAllMyBuckets auth failure} -constraints BucketIO \ -body { S3expectErr { S3::Configure -accesskeyid 44CF9590006BF252F707 \ -secretaccesskey OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV S3::ListAllMyBuckets } } -result "1 S3 remote 403" -match S3err test S3-10.20 {ListAllMyBuckets usage params} -body { S3expectErr { S3::ListAllMyBuckets -blocking false -parse-xml {} -result-type REST } } -result "1 S3 usage -parse-xml" -match S3err test S3-10.30 {ListAllMyBuckets bad params two} -body { S3expectErr {S3::ListAllMyBuckets -xyz hello} } -result "1 S3 usage -xyz" -match S3err test S3-10.40 {ListAllMyBuckets bad params three} -body { S3expectErr {S3::ListAllMyBuckets -blocking false -parse-xml} } -result "1 S3 usage -parse-xml" -match S3err set testLAMB { 9fb13c24488e3d7556693247d5a463c1837c3c8ede28f4094228e6c4eb5d70bddnew@san.rr.comdarren2006-10-29T07:04:48.000Zdarren-test2006-10-29T07:04:48.000Zdarren32006-10-30T22:45:34.000Z} test S3-10.50 {ListAllMyBuckets result parsing RAW} -body { S3::ListAllMyBuckets -parse-xml $testLAMB -result-type xml } -result $testLAMB test S3-10.60 {ListAllMyBuckets result parsing REST} -constraints BucketIO -body { set dict [S3::ListAllMyBuckets -result-type REST] dict get $dict httpstatus } -result "403" test S3-10.70 {ListAllMyBuckets result parsing PXML} -body { set pxml [S3::ListAllMyBuckets -result-type pxml -parse-xml $testLAMB] concat [lindex $pxml 0] [llength $pxml] } -result "ListAllMyBucketsResult 4" test S3-10.80 {ListAllMyBuckets result parsing NAMES} -body { # Note these are defined to be alphabetical, so no sorting needed S3::ListAllMyBuckets -result-type names -parse-xml $testLAMB } -result "darren darren-test darren3" test S3-10.90 {ListAllMyBuckets result parsing DICT} -body { set dict [S3::ListAllMyBuckets -result-type dict -parse-xml $testLAMB] puts [llength $dict] puts [dict get $dict Owner/ID] puts [dict get $dict Owner/DisplayName] puts [dict get $dict Bucket/Name] puts [dict get $dict Bucket/Date] } -output {8 9fb13c24488e3d7556693247d5a463c1837c3c8ede28f4094228e6c4eb5d70bd dnew@san.rr.com darren darren-test darren3 2006-10-29T07:04:48.000Z 2006-10-29T07:04:48.000Z 2006-10-30T22:45:34.000Z } test S3-10.100 {ListAllMyBuckets result parsing OWNER} -body { S3::ListAllMyBuckets -result-type owner -parse-xml $testLAMB } -result {9fb13c24488e3d7556693247d5a463c1837c3c8ede28f4094228e6c4eb5d70bd dnew@san.rr.com} test S3-10.110 {ListAllMyBuckets result parsing error} -body { S3expectErr [list S3::ListAllMyBuckets -result-type xyzzy \ -parse-xml $testLAMB] } -result "1 S3 usage -result-type" -match S3err test S3-10.120 {ListAllMyBuckets result parsing error} -body { S3expectErr {S3::ListAllMyBuckets -result-type xyzzy -parse-xml " 9fb13c24488e3d7556693247d5a463c1837c3c8ede28f4094228e6c4eb5d70bddnew@san.rr.comhttp://acs.amazonaws.com/groups/global/AllUsersFULL_CONTROL9fb13c24488e3d7556693247d5a463c1837c3c8ede28f4094228e6c4eb5d70bddnew@san.rr.comFULL_CONTROLa5ee16f393707820a7f2d58631351fe839972d25865f8fc423a754d77523e6d4darrenREADa1bf9e3c79a243e04e31bf3d1f532aca94646ab917c188831241bf5d575fee92DarrenWRITE} set x2 [S3::GetAcl -parse-xml $xml -result-type dict] return $x2 } -result "owner 9fb13c24488e3d7556693247d5a463c1837c3c8ede28f4094228e6c4eb5d70bd acl {READ a5ee16f393707820a7f2d58631351fe839972d25865f8fc423a754d77523e6d4 WRITE a1bf9e3c79a243e04e31bf3d1f532aca94646ab917c188831241bf5d575fee92 FULL_CONTROL {http://acs.amazonaws.com/groups/global/AllUsers 9fb13c24488e3d7556693247d5a463c1837c3c8ede28f4094228e6c4eb5d70bd}}" test S3-90.50 {PutAcl private} \ -setup $pgsu -cleanup $pgcu -constraints "Acl" -body { set x1 [S3::PutAcl -bucket $bucket -resource "ABC" -acl private] set x2 [S3::GetAcl -bucket $bucket -resource "ABC" -result-type dict] set x3 [dict get $x2 acl] set x4 [llength $x3] return [list [string range $x1 0 19] $x4 [lindex $x3 0]] } -result "