11const assert = require ( 'assert' ) ;
22const {
33 PutObjectCommand,
4+ PutBucketVersioningCommand,
45 HeadObjectCommand,
56 GetObjectCommand,
67} = require ( '@aws-sdk/client-s3' ) ;
78
89const withV4 = require ( '../support/withV4' ) ;
910const BucketUtility = require ( '../../lib/utility/bucket-util' ) ;
11+ const { fakeMetadataArchive, fakeMetadataTransition, getMetadata, initMetadata } = require ( '../utils/init' ) ;
12+
13+ const coldStateScenarios = [
14+ {
15+ name : 'transition in progress' ,
16+ transitionInProgress : true ,
17+ } ,
18+ {
19+ name : 'archived' ,
20+ archiveState : {
21+ archiveInfo : { archiveId : 'archive-1' } ,
22+ restoreRequestedAt : new Date ( 0 ) . toISOString ( ) ,
23+ restoreRequestedDays : 5 ,
24+ } ,
25+ } ,
26+ {
27+ name : 'restored (not expired)' ,
28+ archiveState : {
29+ archiveInfo : { archiveId : 'archive-restored' } ,
30+ restoreRequestedAt : new Date ( 0 ) . toISOString ( ) ,
31+ restoreRequestedDays : 5 ,
32+ restoreCompletedAt : new Date ( Date . now ( ) - 60 * 60 * 1000 ) . toISOString ( ) ,
33+ restoreWillExpireAt : new Date ( Date . now ( ) + 24 * 60 * 60 * 1000 ) . toISOString ( ) ,
34+ } ,
35+ } ,
36+ {
37+ name : 'restored (expired)' ,
38+ archiveState : {
39+ archiveInfo : { archiveId : 'archive-expired' } ,
40+ restoreRequestedAt : new Date ( 0 ) . toISOString ( ) ,
41+ restoreRequestedDays : 5 ,
42+ restoreCompletedAt : new Date ( Date . now ( ) - 48 * 60 * 60 * 1000 ) . toISOString ( ) ,
43+ restoreWillExpireAt : new Date ( Date . now ( ) - 24 * 60 * 60 * 1000 ) . toISOString ( ) ,
44+ } ,
45+ } ,
46+ ] ;
1047
1148const objectName = 'someObject' ;
1249const firstPutMetadata = {
@@ -30,6 +67,7 @@ describe('Put object with same key as prior object', () => {
3067 bucketUtil = new BucketUtility ( 'default' , sigCfg ) ;
3168 s3 = bucketUtil . s3 ;
3269 bucketName = await bucketUtil . createRandom ( 1 ) ;
70+ await initMetadata ( ) ;
3371 } ) ;
3472
3573 beforeEach ( async ( ) => {
@@ -66,5 +104,109 @@ describe('Put object with same key as prior object', () => {
66104 const bodyText = await res . Body . transformToString ( ) ;
67105 assert . deepStrictEqual ( bodyText , 'Much different' ) ;
68106 } ) ;
107+
108+ coldStateScenarios . forEach ( ( { name, transitionInProgress, archiveState } ) => {
109+ it ( `should replace object with cold-state metadata (${ name } ) in non-versioned bucket` , async ( ) => {
110+ if ( transitionInProgress ) {
111+ await fakeMetadataTransition ( bucketName , objectName , undefined ) ;
112+ } else {
113+ await fakeMetadataArchive ( bucketName , objectName , undefined , archiveState ) ;
114+ }
115+
116+ await s3 . send ( new PutObjectCommand ( {
117+ Bucket : bucketName ,
118+ Key : objectName ,
119+ Body : `overwrite cold state ${ name } ` ,
120+ Metadata : secondPutMetadata ,
121+ } ) ) ;
122+
123+ const currentMD = await getMetadata ( bucketName , objectName , undefined ) ;
124+ assert . strictEqual ( currentMD . archive , undefined ) ;
125+ assert . strictEqual ( currentMD [ 'x-amz-scal-transition-in-progress' ] , undefined ) ;
126+ } ) ;
127+ } ) ;
128+
129+ it ( 'should create a new version when replacing archived current object in versioned bucket' , async ( ) => {
130+ await bucketUtil . empty ( bucketName ) ;
131+
132+ await s3 . send ( new PutBucketVersioningCommand ( {
133+ Bucket : bucketName ,
134+ VersioningConfiguration : { Status : 'Enabled' } ,
135+ } ) ) ;
136+
137+ const firstPutRes = await s3 . send ( new PutObjectCommand ( {
138+ Bucket : bucketName ,
139+ Key : objectName ,
140+ Body : 'versioned first payload' ,
141+ Metadata : firstPutMetadata ,
142+ } ) ) ;
143+ assert ( firstPutRes . VersionId ) ;
144+
145+ await fakeMetadataArchive ( bucketName , objectName , undefined , {
146+ archiveInfo : { archiveId : 'archive-versioned-current' } ,
147+ restoreRequestedAt : new Date ( 0 ) . toISOString ( ) ,
148+ restoreRequestedDays : 5 ,
149+ } ) ;
150+
151+ const secondPutRes = await s3 . send ( new PutObjectCommand ( {
152+ Bucket : bucketName ,
153+ Key : objectName ,
154+ Body : 'versioned second payload' ,
155+ Metadata : secondPutMetadata ,
156+ } ) ) ;
157+ assert ( secondPutRes . VersionId ) ;
158+ assert . notStrictEqual ( secondPutRes . VersionId , firstPutRes . VersionId ) ;
159+
160+ const headRes = await s3 . send ( new HeadObjectCommand ( {
161+ Bucket : bucketName ,
162+ Key : objectName ,
163+ } ) ) ;
164+ assert . deepStrictEqual ( headRes . Metadata , secondPutMetadata ) ;
165+
166+ const currentMD = await getMetadata ( bucketName , objectName , undefined ) ;
167+ assert . strictEqual ( currentMD . archive , undefined ) ;
168+ } ) ;
169+
170+ it ( 'should replace archived current null version in version-suspended bucket' , async ( ) => {
171+ await bucketUtil . empty ( bucketName ) ;
172+
173+ await s3 . send ( new PutBucketVersioningCommand ( {
174+ Bucket : bucketName ,
175+ VersioningConfiguration : { Status : 'Enabled' } ,
176+ } ) ) ;
177+ await s3 . send ( new PutObjectCommand ( {
178+ Bucket : bucketName ,
179+ Key : objectName ,
180+ Body : 'enabled-version-payload' ,
181+ } ) ) ;
182+ await s3 . send ( new PutBucketVersioningCommand ( {
183+ Bucket : bucketName ,
184+ VersioningConfiguration : { Status : 'Suspended' } ,
185+ } ) ) ;
186+
187+ await s3 . send ( new PutObjectCommand ( {
188+ Bucket : bucketName ,
189+ Key : objectName ,
190+ Body : 'null-current-before-archive' ,
191+ } ) ) ;
192+
193+ await fakeMetadataArchive ( bucketName , objectName , undefined , {
194+ archiveInfo : { archiveId : 'archive-null-current' } ,
195+ restoreRequestedAt : new Date ( 0 ) . toISOString ( ) ,
196+ restoreRequestedDays : 5 ,
197+ } ) ;
198+
199+ await s3 . send ( new PutObjectCommand ( {
200+ Bucket : bucketName ,
201+ Key : objectName ,
202+ Body : 'replace archived null current' ,
203+ Metadata : secondPutMetadata ,
204+ } ) ) ;
205+
206+ const currentMD = await getMetadata ( bucketName , objectName , undefined ) ;
207+ assert . strictEqual ( currentMD . archive , undefined ) ;
208+ assert . deepStrictEqual ( currentMD [ 'x-amz-meta-secondput' ] , secondPutMetadata . secondput ) ;
209+ } ) ;
210+
69211 } ) ;
70212} ) ;
0 commit comments