@@ -11,6 +11,7 @@ import (
1111 "strings"
1212 "sync"
1313 "testing"
14+ "time"
1415
1516 "github.com/aws/aws-sdk-go-v2/aws"
1617 "github.com/aws/aws-sdk-go-v2/config"
@@ -21,9 +22,10 @@ import (
2122
2223// mockS3Object stores object data and metadata within the mock server.
2324type mockS3Object struct {
24- body []byte
25- metadata map [string ]string
26- crc32c string
25+ body []byte
26+ metadata map [string ]string
27+ crc32c string
28+ lastModified time.Time
2729}
2830
2931// mockS3Server is our mock S3 server, holding an in-memory "bucket".
@@ -117,7 +119,12 @@ func (s *mockS3Server) handlePutRequest(w http.ResponseWriter, r *http.Request,
117119
118120 metadata := s .extractMetadata (r .Header )
119121 crc32c := r .Header .Get ("x-amz-checksum-crc32c" )
120- s .objects [key ] = mockS3Object {body : body , metadata : metadata , crc32c : crc32c }
122+ s .objects [key ] = mockS3Object {
123+ body : body ,
124+ metadata : metadata ,
125+ crc32c : crc32c ,
126+ lastModified : time .Now (),
127+ }
121128 w .WriteHeader (http .StatusOK )
122129}
123130
@@ -129,6 +136,9 @@ func (s *mockS3Server) setObjectHeaders(w http.ResponseWriter, obj mockS3Object)
129136 if obj .crc32c != "" {
130137 w .Header ().Set ("x-amz-checksum-crc32c" , obj .crc32c )
131138 }
139+ if ! obj .lastModified .IsZero () {
140+ w .Header ().Set ("Last-Modified" , obj .lastModified .UTC ().Format (http .TimeFormat ))
141+ }
132142}
133143
134144func (s * mockS3Server ) writeS3NoSuchKeyError (w http.ResponseWriter ) {
@@ -157,6 +167,10 @@ func setupTestS3DataStore(t *testing.T, ctx context.Context, bucketPath string,
157167 }
158168 // Initialize the mock server with provided objects.
159169 for key , obj := range initObjects {
170+ // Ensure lastModified is set if not already set
171+ if obj .lastModified .IsZero () {
172+ obj .lastModified = time .Now ()
173+ }
160174 mockServer .objects [key ] = obj
161175 }
162176 server := httptest .NewServer (mockServer )
@@ -255,6 +269,20 @@ func TestS3PutFile(t *testing.T) {
255269 require .Equal (t , map [string ]string (nil ), metadata )
256270}
257271
272+ func TestS3GetFileLastModified (t * testing.T ) {
273+ ctx := context .Background ()
274+ store , teardown := setupTestS3DataStore (t , ctx , "test-bucket/objects/testnet" , map [string ]mockS3Object {})
275+ defer teardown ()
276+
277+ content := []byte ("inside the file" )
278+ err := store .PutFile (ctx , "file.txt" , bytes .NewReader (content ), nil )
279+ require .NoError (t , err )
280+
281+ lastModified , err := store .GetFileLastModified (context .Background (), "file.txt" )
282+ require .NoError (t , err )
283+ require .NotZero (t , lastModified )
284+ }
285+
258286func TestS3PutFileIfNotExists (t * testing.T ) {
259287 ctx := context .Background ()
260288 store , teardown := setupTestS3DataStore (t , ctx , "test-bucket/objects/testnet" , map [string ]mockS3Object {})
@@ -424,9 +452,10 @@ func TestS3GetFileValidatesCRC32C(t *testing.T) {
424452 ctx := context .Background ()
425453 store , teardown := setupTestS3DataStore (t , ctx , "test-bucket/objects/testnet" , map [string ]mockS3Object {
426454 "objects/testnet/file.txt" : {
427- body : []byte ("hello" ),
428- metadata : map [string ]string {},
429- crc32c : "VLn+tw==" , // invalid CRC32C for the content
455+ body : []byte ("hello" ),
456+ metadata : map [string ]string {},
457+ crc32c : "VLn+tw==" , // invalid CRC32C for the content
458+ lastModified : time .Now (),
430459 }})
431460 defer teardown ()
432461
0 commit comments