@@ -16,9 +16,9 @@ import AsyncHTTPClient
1616import Atomics
1717import NIOCore
1818import NIOPosix
19- import SotoCore
2019import XCTest
2120
21+ @testable import SotoCore
2222@testable import SotoS3
2323@testable import SotoS3Control
2424
@@ -68,7 +68,10 @@ class S3Tests: XCTestCase {
6868 }
6969
7070 static func deleteBucket( name: String , s3: S3 ) async throws {
71- let response = try await s3. listObjectsV2 ( . init( bucket: name) , logger: TestEnvironment . logger)
71+ let response = try await s3. listObjectsV2 (
72+ . init( bucket: name) ,
73+ logger: TestEnvironment . logger
74+ )
7275 if let contents = response. contents {
7376 let request = S3 . DeleteObjectsRequest (
7477 bucket: name,
@@ -80,7 +83,13 @@ class S3Tests: XCTestCase {
8083 }
8184
8285 /// create S3 bucket with supplied name and run supplied closure
83- func testBucket( _ name: String , s3: S3 ? = nil , test: @escaping ( String ) async throws -> Void ) async throws {
86+ func testBucket(
87+ _ name: String ,
88+ s3: S3 ? = nil ,
89+ test: @escaping ( String ) async throws -> Void
90+ )
91+ async throws
92+ {
8493 let s3 = s3 ?? Self . s3!
8594 try await XCTTestAsset {
8695 try await Self . createBucket ( name: name, s3: s3)
@@ -93,7 +102,14 @@ class S3Tests: XCTestCase {
93102 }
94103
95104 /// Test putObject to S3 and that getObject returns the same object
96- func testPutGetObject( bucket: String , filename: String , contents: AWSHTTPBody , s3: S3 ? = nil ) async throws {
105+ func testPutGetObject(
106+ bucket: String ,
107+ filename: String ,
108+ contents: AWSHTTPBody ,
109+ s3: S3 ? = nil
110+ )
111+ async throws
112+ {
97113 let s3 = s3 ?? Self . s3!
98114 try await self . testBucket ( bucket, s3: s3) { name in
99115 let putRequest = S3 . PutObjectRequest (
@@ -103,7 +119,9 @@ class S3Tests: XCTestCase {
103119 )
104120 let putResponse = try await s3. putObject ( putRequest)
105121 XCTAssertNotNil ( putResponse. eTag)
106- let getResponse = try await s3. getObject ( . init( bucket: name, key: filename, responseExpires: Date ( ) ) )
122+ let getResponse = try await s3. getObject (
123+ . init( bucket: name, key: filename, responseExpires: Date ( ) )
124+ )
107125 let requestContents = try await contents. collect ( upTo: . max)
108126 let responseContents = try await getResponse. body. collect ( upTo: . max)
109127 XCTAssertEqual ( responseContents, requestContents)
@@ -150,9 +168,15 @@ class S3Tests: XCTestCase {
150168 )
151169 let putResponse = try await Self . s3. putObject ( putRequest)
152170 XCTAssertNotNil ( putResponse. eTag)
153- let copyRequest = S3 . CopyObjectRequest ( bucket: name, copySource: " \( name) / \( keyName) " , key: newKeyName)
171+ let copyRequest = S3 . CopyObjectRequest (
172+ bucket: name,
173+ copySource: " \( name) / \( keyName) " ,
174+ key: newKeyName
175+ )
154176 _ = try await Self . s3. copyObject ( copyRequest)
155- let getResponse = try await Self . s3. getObject ( . init( bucket: name, key: newKeyName, responseExpires: Date ( ) ) )
177+ let getResponse = try await Self . s3. getObject (
178+ . init( bucket: name, key: newKeyName, responseExpires: Date ( ) )
179+ )
156180 let responseContents = try await getResponse. body. collect ( upTo: . max)
157181 XCTAssertEqual ( String ( buffer: responseContents) , contents)
158182 XCTAssertNotNil ( getResponse. lastModified)
@@ -208,7 +232,11 @@ class S3Tests: XCTestCase {
208232 let name = TestEnvironment . generateResourceName ( )
209233 let contents = " testing S3.ListObjectsV2 "
210234 try await self . testBucket ( name) { name in
211- let putRequest = S3 . PutObjectRequest ( body: . init( string: contents) , bucket: name, key: name)
235+ let putRequest = S3 . PutObjectRequest (
236+ body: . init( string: contents) ,
237+ bucket: name,
238+ key: name
239+ )
212240 let putResponse = try await Self . s3. putObject ( putRequest)
213241 let eTag = putResponse. eTag
214242 let listResponse = try await Self . s3. listObjectsV2 ( . init( bucket: name) )
@@ -269,7 +297,10 @@ class S3Tests: XCTestCase {
269297 throw Disable100CompleteError ( header: request. headers [ " Expect " ] . first)
270298 }
271299 }
272- let s3 = Self . s3. with ( middleware: Disable100CompleteMiddleware ( ) , options: . s3Disable100Continue)
300+ let s3 = Self . s3. with (
301+ middleware: Disable100CompleteMiddleware ( ) ,
302+ options: . s3Disable100Continue
303+ )
273304 let name = TestEnvironment . generateResourceName ( )
274305 let byteBuffer = Self . createRandomBuffer ( size: 8 * 1024 )
275306
@@ -291,7 +322,8 @@ class S3Tests: XCTestCase {
291322 let name = TestEnvironment . generateResourceName ( )
292323 try await self . testBucket ( name) { name in
293324 // set lifecycle rules
294- let incompleteMultipartUploads = S3 . AbortIncompleteMultipartUpload ( daysAfterInitiation: 7 ) // clear incomplete multipart uploads after 7 days
325+ // clear incomplete multipart uploads after 7 days
326+ let incompleteMultipartUploads = S3 . AbortIncompleteMultipartUpload ( daysAfterInitiation: 7 )
295327 let filter = S3 . LifecycleRuleFilter ( prefix: " " ) // everything
296328 let transitions = [ S3 . Transition ( days: 14 , storageClass: . glacier) ] // transition objects to glacier after 14 days
297329 let lifecycleRules = S3 . LifecycleRule (
@@ -301,13 +333,19 @@ class S3Tests: XCTestCase {
301333 status: . enabled,
302334 transitions: transitions
303335 )
304- let request = S3 . PutBucketLifecycleConfigurationRequest ( bucket: name, lifecycleConfiguration: . init( rules: [ lifecycleRules] ) )
336+ let request = S3 . PutBucketLifecycleConfigurationRequest (
337+ bucket: name,
338+ lifecycleConfiguration: . init( rules: [ lifecycleRules] )
339+ )
305340 _ = try await Self . s3. putBucketLifecycleConfiguration ( request)
306341
307342 let getResponse = try await Self . s3. getBucketLifecycleConfiguration ( . init( bucket: name) )
308343 XCTAssertEqual ( getResponse. rules ? [ 0 ] . transitions ? [ 0 ] . storageClass, . glacier)
309344 XCTAssertEqual ( getResponse. rules ? [ 0 ] . transitions ? [ 0 ] . days, 14 )
310- XCTAssertEqual ( getResponse. rules ? [ 0 ] . abortIncompleteMultipartUpload? . daysAfterInitiation, 7 )
345+ XCTAssertEqual (
346+ getResponse. rules ? [ 0 ] . abortIncompleteMultipartUpload? . daysAfterInitiation,
347+ 7
348+ )
311349 }
312350 }
313351
@@ -343,7 +381,9 @@ class S3Tests: XCTestCase {
343381 key: name
344382 )
345383 _ = try await Self . s3. putObject ( putRequest)
346- let getACLResponse = try await Self . s3. getObjectAcl ( . init( bucket: name, key: name, requestPayer: . requester) )
384+ let getACLResponse = try await Self . s3. getObjectAcl (
385+ . init( bucket: name, key: name, requestPayer: . requester)
386+ )
347387 print ( getACLResponse)
348388 }
349389 }
@@ -354,7 +394,9 @@ class S3Tests: XCTestCase {
354394 try await _ = ( 0 ..< 16 ) . concurrentMap {
355395 let body = " testMultipleUpload - " + $0. description
356396 let filename = " file " + $0. description
357- _ = try await Self . s3. putObject ( . init( body: . init( string: body) , bucket: name, key: filename) )
397+ _ = try await Self . s3. putObject (
398+ . init( body: . init( string: body) , bucket: name, key: filename)
399+ )
358400 }
359401
360402 let paginator = Self . s3. listObjectsV2Paginator ( . init( bucket: name, maxKeys: 5 ) )
@@ -385,7 +427,10 @@ class S3Tests: XCTestCase {
385427 try await self . testPutGetObject (
386428 bucket: name,
387429 filename: " testfile.txt " ,
388- contents: . init( asyncSequence: byteBuffer. asyncSequence ( chunkSize: chunkSize) , length: byteBuffer. readableBytes) ,
430+ contents: . init(
431+ asyncSequence: byteBuffer. asyncSequence ( chunkSize: chunkSize) ,
432+ length: byteBuffer. readableBytes
433+ ) ,
389434 s3: s3
390435 )
391436 }
@@ -421,11 +466,17 @@ class S3Tests: XCTestCase {
421466 try XCTSkipIf ( TestEnvironment . isUsingLocalstack)
422467
423468 let name = TestEnvironment . generateResourceName ( )
424- let s3Url = URL ( string: " https:// \( name) .s3.us-east-1.amazonaws.com/ \( name) !=%25+/(*)_.txt " ) !
469+ let s3Url = URL (
470+ string: " https:// \( name) .s3.us-east-1.amazonaws.com/ \( name) !=%25+/(*)_.txt "
471+ ) !
425472
426473 try await testBucket ( name) { _ in
427474 let byteBuffer = Self . createRandomBuffer ( size: 186 )
428- let putURL = try await Self . s3. signURL ( url: s3Url, httpMethod: . PUT, expires: . minutes( 5 ) )
475+ let putURL = try await Self . s3. signURL (
476+ url: s3Url,
477+ httpMethod: . PUT,
478+ expires: . minutes( 5 )
479+ )
429480 var request = HTTPClientRequest ( url: putURL. absoluteString)
430481 request. method = . PUT
431482 request. body = . bytes( byteBuffer)
@@ -435,8 +486,15 @@ class S3Tests: XCTestCase {
435486 let listResponse = try await Self . s3. listObjectsV2 ( . init( bucket: name) )
436487 XCTAssertEqual ( listResponse. contents? . first? . key, " \( name) !=%+/(*)_.txt " )
437488
438- let getURL = try await Self . s3. signURL ( url: s3Url, httpMethod: . GET, expires: . minutes( 5 ) )
439- let getResponse = try await HTTPClient . shared. execute ( . init( url: getURL. absoluteString) , timeout: . minutes( 1 ) )
489+ let getURL = try await Self . s3. signURL (
490+ url: s3Url,
491+ httpMethod: . GET,
492+ expires: . minutes( 5 )
493+ )
494+ let getResponse = try await HTTPClient . shared. execute (
495+ . init( url: getURL. absoluteString) ,
496+ timeout: . minutes( 1 )
497+ )
440498
441499 let getBuffer = try await getResponse. body. collect ( upTo: . max)
442500 XCTAssertEqual ( response. status, . ok)
@@ -523,7 +581,10 @@ class S3Tests: XCTestCase {
523581 let filename = " testfile.txt "
524582 let contents = " testing S3.PutObject and S3.GetObject "
525583 // set acceleration configuration
526- let request = S3 . PutBucketAccelerateConfigurationRequest ( accelerateConfiguration: . init( status: . enabled) , bucket: name)
584+ let request = S3 . PutBucketAccelerateConfigurationRequest (
585+ accelerateConfiguration: . init( status: . enabled) ,
586+ bucket: name
587+ )
527588 _ = try await Self . s3. putBucketAccelerateConfiguration ( request)
528589
529590 let putRequest = S3 . PutObjectRequest (
@@ -533,7 +594,9 @@ class S3Tests: XCTestCase {
533594 )
534595 let putResponse = try await s3Accelerated. putObject ( putRequest)
535596 XCTAssertNotNil ( putResponse. eTag)
536- let getResponse = try await s3Accelerated. getObject ( . init( bucket: name, key: filename, responseExpires: Date ( ) ) )
597+ let getResponse = try await s3Accelerated. getObject (
598+ . init( bucket: name, key: filename, responseExpires: Date ( ) )
599+ )
537600 let responseContents = try await getResponse. body. collect ( upTo: . max)
538601 XCTAssertEqual ( String ( buffer: responseContents) , contents)
539602 XCTAssertNotNil ( getResponse. lastModified)
@@ -546,7 +609,9 @@ class S3Tests: XCTestCase {
546609 let filename = " testfile.txt "
547610 let contents = " testing S3.PutObject and S3.GetObject "
548611
549- _ = try await Self . s3. putObject ( . init( body: . init( string: contents) , bucket: name, key: filename) )
612+ _ = try await Self . s3. putObject (
613+ . init( body: . init( string: contents) , bucket: name, key: filename)
614+ )
550615 try await Self . s3. waitUntilObjectExists ( . init( bucket: name, key: filename) )
551616
552617 _ = try await Self . s3. deleteObject ( . init( bucket: name, key: filename) )
@@ -577,7 +642,9 @@ class S3Tests: XCTestCase {
577642 throw CancelError ( )
578643 }
579644 }
580- let s3Control = S3Control ( client: Self . client, region: . euwest1) . with ( middleware: CheckHostMiddleware ( ) )
645+ let s3Control = S3Control ( client: Self . client, region: . euwest1) . with (
646+ middleware: CheckHostMiddleware ( )
647+ )
581648 let request = S3Control . ListJobsRequest ( accountId: " 123456780123 " )
582649 do {
583650 _ = try await s3Control. listJobs ( request)
@@ -636,4 +703,34 @@ class S3Tests: XCTestCase {
636703 }
637704 }
638705 }
706+
707+ /// test S3 control host is prefixed with account id
708+ func testS3AccessPoints( ) async throws {
709+ // doesnt work with LocalStack
710+ try XCTSkipIf ( TestEnvironment . isUsingLocalstack)
711+ guard let accountId = Environment [ " AWS_ACCOUNT_ID " ] else { throw XCTSkip ( ) }
712+ let name = TestEnvironment . generateResourceName ( )
713+ try await self . testBucket ( name) { name in
714+ let s3Control = S3Control ( client: Self . client, region: Self . s3. region)
715+ let response = try await s3Control. createAccessPoint (
716+ accountId: accountId,
717+ bucket: name,
718+ name: " test-accesspoint " ,
719+ logger: TestEnvironment . logger
720+ )
721+ return try await withTeardown {
722+ let accessPointArn = try XCTUnwrap ( response. accessPointArn)
723+ let alias = try XCTUnwrap ( response. alias)
724+ let string = " testing S3.PutObject and S3.GetObject "
725+ // upload using arn
726+ _ = try await Self . s3. putObject ( body: . init( string: string) , bucket: accessPointArn, key: name, logger: TestEnvironment . logger)
727+ // download using alias
728+ let getObjectResponse = try await Self . s3. getObject ( bucket: alias, key: name, logger: TestEnvironment . logger)
729+ let body = try await getObjectResponse. body. collect ( upTo: . max)
730+ XCTAssertEqual ( String ( buffer: body) , string)
731+ } teardown: {
732+ try ? await s3Control. deleteAccessPoint ( accountId: accountId, name: " test-accesspoint " , logger: TestEnvironment . logger)
733+ }
734+ }
735+ }
639736}
0 commit comments