Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support versioning #1895

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Of these [operations of the Amazon S3 API](https://docs.aws.amazon.com/AmazonS3/
| [GetBucketReplication](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketReplication.html) | :x: | |
| [GetBucketRequestPayment](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketRequestPayment.html) | :x: | |
| [GetBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html) | :x: | |
| [GetBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) | :x: | |
| [GetBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html) | :white_check_mark: | |
| [GetBucketWebsite](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketWebsite.html) | :x: | |
| [GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html) | :white_check_mark: | |
| [GetObjectAcl](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html) | :white_check_mark: | |
Expand Down Expand Up @@ -144,7 +144,7 @@ Of these [operations of the Amazon S3 API](https://docs.aws.amazon.com/AmazonS3/
| [PutBucketReplication](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketReplication.html) | :x: | |
| [PutBucketRequestPayment](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketRequestPayment.html) | :x: | |
| [PutBucketTagging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html) | :x: | |
| [PutBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html) | :x: | |
| [PutBucketVersioning](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html) | :white_check_mark: | |
| [PutBucketWebsite](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketWebsite.html) | :x: | |
| [PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) | :white_check_mark: | |
| [PutObjectAcl](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectAcl.html) | :white_check_mark: | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,24 @@ import software.amazon.awssdk.awscore.exception.AwsServiceException
import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.services.s3.model.AbortIncompleteMultipartUpload
import software.amazon.awssdk.services.s3.model.BucketLifecycleConfiguration
import software.amazon.awssdk.services.s3.model.BucketVersioningStatus
import software.amazon.awssdk.services.s3.model.CreateBucketRequest
import software.amazon.awssdk.services.s3.model.DeleteBucketLifecycleRequest
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest
import software.amazon.awssdk.services.s3.model.ExpirationStatus
import software.amazon.awssdk.services.s3.model.GetBucketLifecycleConfigurationRequest
import software.amazon.awssdk.services.s3.model.GetBucketLocationRequest
import software.amazon.awssdk.services.s3.model.GetBucketVersioningRequest
import software.amazon.awssdk.services.s3.model.HeadBucketRequest
import software.amazon.awssdk.services.s3.model.LifecycleExpiration
import software.amazon.awssdk.services.s3.model.LifecycleRule
import software.amazon.awssdk.services.s3.model.LifecycleRuleFilter
import software.amazon.awssdk.services.s3.model.MFADelete
import software.amazon.awssdk.services.s3.model.MFADeleteStatus
import software.amazon.awssdk.services.s3.model.NoSuchBucketException
import software.amazon.awssdk.services.s3.model.PutBucketLifecycleConfigurationRequest
import software.amazon.awssdk.services.s3.model.PutBucketVersioningRequest
import software.amazon.awssdk.services.s3.model.VersioningConfiguration
import java.util.concurrent.TimeUnit

/**
Expand Down Expand Up @@ -79,6 +85,52 @@ internal class BucketV2IT : S3TestBase() {
assertThat(bucketLocation.locationConstraint().toString()).isEqualTo("eu-west-1")
}

@Test
@S3VerifiedSuccess(year = 2024)
fun getDefaultBucketVersioning(testInfo: TestInfo) {
val bucketName = givenBucketV2(testInfo)

s3ClientV2.getBucketVersioning(
GetBucketVersioningRequest
.builder()
.bucket(bucketName)
.build()
).also {
assertThat(it.status()).isNull()
assertThat(it.mfaDelete()).isNull()
}
}

@Test
@S3VerifiedFailure(year = 2024, reason = "No real Mfa value")
fun putAndGetBucketVersioning(testInfo: TestInfo) {
val bucketName = givenBucketV2(testInfo)
s3ClientV2.putBucketVersioning(
PutBucketVersioningRequest
.builder()
.bucket(bucketName)
.mfa("fakeMfaValue")
.versioningConfiguration(
VersioningConfiguration
.builder()
.status(BucketVersioningStatus.ENABLED)
.mfaDelete(MFADelete.ENABLED)
.build()
)
.build()
)

s3ClientV2.getBucketVersioning(
GetBucketVersioningRequest
.builder()
.bucket(bucketName)
.build()
).also {
assertThat(it.status()).isEqualTo(BucketVersioningStatus.ENABLED)
assertThat(it.mfaDelete()).isEqualTo(MFADeleteStatus.ENABLED)
}
}

@Test
@S3VerifiedSuccess(year = 2024)
fun duplicateBucketCreation(testInfo: TestInfo) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@
package com.adobe.testing.s3mock.its

import com.adobe.testing.s3mock.util.DigestUtil
import org.apache.http.HttpHost
import org.apache.http.HttpStatus
import org.apache.http.client.methods.HttpOptions
import org.apache.http.client.methods.HttpPut
import org.apache.http.entity.ByteArrayEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.impl.client.HttpClients
import org.apache.http.message.BasicHeader
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
Expand All @@ -36,35 +33,28 @@ import java.util.UUID
* Test the application using the AmazonS3 SDK V2.
*/
internal class CorsV2IT : S3TestBase() {
private val httpClient: CloseableHttpClient = HttpClients.createDefault()
private val httpClient: CloseableHttpClient = createHttpClient()

@Test
@S3VerifiedFailure(year = 2024,
reason = "No credentials sent in plain HTTP request")
fun testPutObject_cors(testInfo: TestInfo) {
val bucketName = givenBucketV2(testInfo)
val httpclient = HttpClientBuilder.create().build()
val optionsRequest = HttpOptions("/${bucketName}/testObjectName").apply {
val optionsRequest = HttpOptions("$serviceEndpoint/${bucketName}/testObjectName").apply {
this.addHeader("Origin", "http://localhost/")
}
httpclient.execute(HttpHost(
host, httpPort
), optionsRequest).also {
httpClient.execute(optionsRequest).also {
assertThat(it.getFirstHeader("Allow").value).contains("PUT")
}

val byteArray = UUID.randomUUID().toString().toByteArray()
val expectedEtag = "\"${DigestUtil.hexDigest(byteArray)}\""
val putObject = HttpPut("/$bucketName/testObjectName").apply {
val putObject = HttpPut("$serviceEndpoint/$bucketName/testObjectName").apply {
this.entity = ByteArrayEntity(byteArray)
this.addHeader("Origin", "http://localhost/")
}

httpClient.execute(
HttpHost(
host, httpPort
), putObject
).use {
httpClient.execute(putObject).use {
assertThat(it.statusLine.statusCode).isEqualTo(HttpStatus.SC_OK)
assertThat(it.getFirstHeader("ETag").value).isEqualTo(expectedEtag)
assertThat(it.getFirstHeader("Access-Control-Allow-Origin").value).isEqualTo("*")
Expand All @@ -77,17 +67,13 @@ internal class CorsV2IT : S3TestBase() {
reason = "No credentials sent in plain HTTP request")
fun testGetBucket_cors(testInfo: TestInfo) {
val targetBucket = givenBucketV2(testInfo)
val httpOptions = HttpOptions("/$targetBucket").apply {
val httpOptions = HttpOptions("$serviceEndpoint/$targetBucket").apply {
this.addHeader(BasicHeader("Origin", "http://someurl.com"))
this.addHeader(BasicHeader("Access-Control-Request-Method", "GET"))
this.addHeader(BasicHeader("Access-Control-Request-Headers", "Content-Type, x-requested-with"))
}

httpClient.execute(
HttpHost(
host, httpPort
), httpOptions
).use {
httpClient.execute(httpOptions).use {
assertThat(it.getFirstHeader("Access-Control-Allow-Origin").value).isEqualTo("http://someurl.com")
assertThat(it.getFirstHeader("Access-Control-Allow-Methods").value).isEqualTo("GET")
assertThat(it.getFirstHeader("Access-Control-Allow-Headers").value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ import com.amazonaws.services.s3.model.PutObjectRequest
import com.amazonaws.services.s3.model.ResponseHeaderOverrides
import com.amazonaws.services.s3.model.SSEAwsKeyManagementParams
import com.amazonaws.services.s3.transfer.TransferManager
import org.apache.http.HttpHost
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.HttpClients
import org.apache.http.impl.client.CloseableHttpClient
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.assertj.core.configuration.Configuration
Expand All @@ -47,14 +46,14 @@ import java.io.FileInputStream
import java.io.InputStream
import java.util.UUID
import java.util.stream.Collectors
import javax.net.ssl.HostnameVerifier
import kotlin.math.min

/**
* Test the application using the AmazonS3 SDK V1.
*/
internal class GetPutDeleteObjectV1IT : S3TestBase() {

private val httpClient: CloseableHttpClient = createHttpClient()
private val s3Client: AmazonS3 = createS3ClientV1()
private val transferManagerV1: TransferManager = createTransferManagerV1()

Expand Down Expand Up @@ -459,12 +458,10 @@ internal class GetPutDeleteObjectV1IT : S3TestBase() {
)
this.method = HttpMethod.GET
}
val resourceUrl = createS3ClientV1(serviceEndpointHttp).generatePresignedUrl(presignedUrlRequest)
HttpClients.createDefault().use {
val resourceUrl = s3Client.generatePresignedUrl(presignedUrlRequest)
httpClient.use {
val getObject = HttpGet(resourceUrl.toString())
it.execute(
getObject
).also { response ->
it.execute(getObject).also { response ->
assertThat(response.getFirstHeader(Headers.CACHE_CONTROL).value).isEqualTo("cacheControl")
assertThat(response.getFirstHeader(Headers.CONTENT_DISPOSITION).value).isEqualTo("contentDisposition")
assertThat(response.getFirstHeader(Headers.CONTENT_ENCODING).value).isEqualTo("contentEncoding")
Expand Down
Loading