Skip to content

Commit 230389e

Browse files
committed
CopyObject conditional request ITs
Fixes #2371
1 parent 384ddda commit 230389e

File tree

1 file changed

+122
-0
lines changed
  • integration-tests/src/test/kotlin/com/adobe/testing/s3mock/its

1 file changed

+122
-0
lines changed

integration-tests/src/test/kotlin/com/adobe/testing/s3mock/its/CopyObjectIT.kt

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import java.time.Duration
3535
import java.time.Instant
3636
import java.time.temporal.ChronoUnit.SECONDS
3737
import java.util.concurrent.Executors
38+
import java.util.concurrent.TimeUnit
3839

3940
/**
4041
* Test the application using the AmazonS3 SDK V2.
@@ -133,6 +134,127 @@ internal class CopyObjectIT : S3TestBase() {
133134
}
134135
}
135136

137+
@Test
138+
@S3VerifiedSuccess(year = 2025)
139+
fun `copy object with if match true and if unmodified since false succeeds and object can be retrieved`(testInfo: TestInfo) {
140+
val sourceKey = UPLOAD_FILE_NAME
141+
val (bucketName, putObjectResult) = givenBucketAndObject(testInfo, sourceKey)
142+
TimeUnit.SECONDS.sleep(5)
143+
val now = Instant.now()
144+
val destinationBucketName = givenBucket()
145+
val destinationKey = "copyOf/$sourceKey"
146+
147+
val matchingEtag = putObjectResult.eTag()
148+
149+
s3Client.copyObject {
150+
it.sourceBucket(bucketName)
151+
it.sourceKey(sourceKey)
152+
it.destinationBucket(destinationBucketName)
153+
it.destinationKey(destinationKey)
154+
it.copySourceIfMatch(matchingEtag)
155+
it.copySourceIfUnmodifiedSince(now)
156+
}.copyObjectResult().eTag().also {
157+
assertThat(it).isEqualTo(putObjectResult.eTag())
158+
}
159+
160+
s3Client.getObject {
161+
it.bucket(destinationBucketName)
162+
it.key(destinationKey)
163+
}.use {
164+
val copiedDigest = DigestUtil.hexDigest(it)
165+
assertThat("\"$copiedDigest\"").isEqualTo(matchingEtag)
166+
}
167+
}
168+
169+
@Test
170+
@S3VerifiedSuccess(year = 2025)
171+
fun `copy object with if modified since succeeds and object can be retrieved`(testInfo: TestInfo) {
172+
val sourceKey = UPLOAD_FILE_NAME
173+
val now = Instant.now()
174+
TimeUnit.SECONDS.sleep(5)
175+
val (bucketName, putObjectResult) = givenBucketAndObject(testInfo, sourceKey)
176+
val destinationBucketName = givenBucket()
177+
val destinationKey = "copyOf/$sourceKey"
178+
179+
val matchingEtag = putObjectResult.eTag()
180+
181+
s3Client.copyObject {
182+
it.sourceBucket(bucketName)
183+
it.sourceKey(sourceKey)
184+
it.destinationBucket(destinationBucketName)
185+
it.destinationKey(destinationKey)
186+
it.copySourceIfModifiedSince(now)
187+
}.copyObjectResult().eTag().also {
188+
assertThat(it).isEqualTo(putObjectResult.eTag())
189+
}
190+
191+
s3Client.getObject {
192+
it.bucket(destinationBucketName)
193+
it.key(destinationKey)
194+
}.use {
195+
val copiedDigest = DigestUtil.hexDigest(it)
196+
assertThat("\"$copiedDigest\"").isEqualTo(matchingEtag)
197+
}
198+
}
199+
200+
@Test
201+
@S3VerifiedSuccess(year = 2025)
202+
fun `copy object with if modified since true and if none match false fails`(testInfo: TestInfo) {
203+
val sourceKey = UPLOAD_FILE_NAME
204+
val now = Instant.now()
205+
TimeUnit.SECONDS.sleep(5)
206+
val (bucketName, putObjectResult) = givenBucketAndObject(testInfo, sourceKey)
207+
val destinationBucketName = givenBucket()
208+
val destinationKey = "copyOf/$sourceKey"
209+
210+
val matchingEtag = putObjectResult.eTag()
211+
212+
assertThatThrownBy {
213+
s3Client.copyObject {
214+
it.sourceBucket(bucketName)
215+
it.sourceKey(sourceKey)
216+
it.destinationBucket(destinationBucketName)
217+
it.destinationKey(destinationKey)
218+
it.copySourceIfModifiedSince(now)
219+
it.copySourceIfNoneMatch(matchingEtag)
220+
}
221+
}
222+
.isInstanceOf(S3Exception::class.java)
223+
.hasMessageContaining("Service: S3, Status Code: 412")
224+
.hasMessageContaining(PRECONDITION_FAILED.message)
225+
}
226+
227+
@Test
228+
@S3VerifiedSuccess(year = 2025)
229+
fun `copy object with if unmodified since succeeds and object can be retrieved`(testInfo: TestInfo) {
230+
val sourceKey = UPLOAD_FILE_NAME
231+
val (bucketName, putObjectResult) = givenBucketAndObject(testInfo, sourceKey)
232+
TimeUnit.SECONDS.sleep(5)
233+
val now = Instant.now()
234+
val destinationBucketName = givenBucket()
235+
val destinationKey = "copyOf/$sourceKey"
236+
237+
val matchingEtag = putObjectResult.eTag()
238+
239+
s3Client.copyObject {
240+
it.sourceBucket(bucketName)
241+
it.sourceKey(sourceKey)
242+
it.destinationBucket(destinationBucketName)
243+
it.destinationKey(destinationKey)
244+
it.copySourceIfUnmodifiedSince(now)
245+
}.copyObjectResult().eTag().also {
246+
assertThat(it).isEqualTo(putObjectResult.eTag())
247+
}
248+
249+
s3Client.getObject {
250+
it.bucket(destinationBucketName)
251+
it.key(destinationKey)
252+
}.use {
253+
val copiedDigest = DigestUtil.hexDigest(it)
254+
assertThat("\"$copiedDigest\"").isEqualTo(matchingEtag)
255+
}
256+
}
257+
136258
@Test
137259
@S3VerifiedSuccess(year = 2025)
138260
fun `copy object with if nonematch succeeds and object can be retrieved`(testInfo: TestInfo) {

0 commit comments

Comments
 (0)