Skip to content

Commit efd1de2

Browse files
authored
chore(storage): Plumb finalize_time through attrs. (googleapis#11643)
* chore(storage): Plumb finalize_time through attrs. * update emulator test to demonstrate finalize time is expected on non-appendable objects * confirm that created time == finalized time for non-appendable objects
1 parent a0e178d commit efd1de2

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

storage/client_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,18 @@ func TestOpenWriterEmulated(t *testing.T) {
939939
if diff := cmp.Diff(got, randomBytesToWrite); diff != "" {
940940
t.Fatalf("checking written content: got(-),want(+):\n%s", diff)
941941
}
942+
943+
o, err := veneerClient.Bucket(bucket).Object(want.Name).Attrs(ctx)
944+
if err != nil {
945+
t.Fatalf("getting object attrs: got %v; want ok", err)
946+
}
947+
if o.Finalized.IsZero() {
948+
t.Errorf("expected valid finalize time: got %v; want non-zero", o.Finalized)
949+
}
950+
// For non-appendable objects, created and finalized times are equal.
951+
if !o.Finalized.Equal(o.Created) {
952+
t.Errorf("expected equal created and finalize times: created %v; finalized %v", o.Created, o.Finalized)
953+
}
942954
})
943955
}
944956

storage/storage.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,7 @@ func (o *ObjectAttrs) toProtoObject(b string) *storagepb.Object {
13321332
Acl: toProtoObjectACL(o.ACL),
13331333
Metadata: o.Metadata,
13341334
CreateTime: toProtoTimestamp(o.Created),
1335+
FinalizeTime: toProtoTimestamp(o.Finalized),
13351336
CustomTime: toProtoTimestamp(o.CustomTime),
13361337
DeleteTime: toProtoTimestamp(o.Deleted),
13371338
RetentionExpireTime: toProtoTimestamp(o.RetentionExpirationTime),
@@ -1494,6 +1495,10 @@ type ObjectAttrs struct {
14941495
// Created is the time the object was created. This field is read-only.
14951496
Created time.Time
14961497

1498+
// Finalized is the time the object contents were finalized. This may differ
1499+
// from Created for appendable objects. This field is read-only.
1500+
Finalized time.Time
1501+
14971502
// Deleted is the time the object was deleted.
14981503
// If not deleted, it is the zero value. This field is read-only.
14991504
Deleted time.Time
@@ -1658,6 +1663,7 @@ func newObject(o *raw.Object) *ObjectAttrs {
16581663
CustomerKeySHA256: sha256,
16591664
KMSKeyName: o.KmsKeyName,
16601665
Created: convertTime(o.TimeCreated),
1666+
Finalized: convertTime(o.TimeFinalized),
16611667
Deleted: convertTime(o.TimeDeleted),
16621668
Updated: convertTime(o.Updated),
16631669
Etag: o.Etag,
@@ -1697,6 +1703,7 @@ func newObjectFromProto(o *storagepb.Object) *ObjectAttrs {
16971703
CustomerKeySHA256: base64.StdEncoding.EncodeToString(o.GetCustomerEncryption().GetKeySha256Bytes()),
16981704
KMSKeyName: o.GetKmsKey(),
16991705
Created: convertProtoTime(o.GetCreateTime()),
1706+
Finalized: convertProtoTime(o.GetFinalizeTime()),
17001707
Deleted: convertProtoTime(o.GetDeleteTime()),
17011708
Updated: convertProtoTime(o.GetUpdateTime()),
17021709
CustomTime: convertProtoTime(o.GetCustomTime()),
@@ -1844,6 +1851,7 @@ var attrToFieldMap = map[string]string{
18441851
"CustomerKeySHA256": "customerEncryption",
18451852
"KMSKeyName": "kmsKeyName",
18461853
"Created": "timeCreated",
1854+
"Finalized": "timeFinalized",
18471855
"Deleted": "timeDeleted",
18481856
"Updated": "updated",
18491857
"Etag": "etag",
@@ -1872,6 +1880,7 @@ var attrToProtoFieldMap = map[string]string{
18721880
"Deleted": "delete_time",
18731881
"ContentType": "content_type",
18741882
"Created": "create_time",
1883+
"Finalized": "finalize_time",
18751884
"CRC32C": "checksums.crc32c",
18761885
"MD5": "checksums.md5_hash",
18771886
"Updated": "update_time",

storage/storage_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,13 +1805,15 @@ func TestRawObjectToObjectAttrs(t *testing.T) {
18051805
RetentionExpirationTime: "2019-03-31T19:33:36Z",
18061806
Size: 1 << 20,
18071807
TimeCreated: "2019-03-31T19:32:10Z",
1808+
TimeFinalized: "2019-03-31T19:32:10Z",
18081809
TimeDeleted: "2019-03-31T19:33:39Z",
18091810
TemporaryHold: true,
18101811
ComponentCount: 2,
18111812
},
18121813
want: &ObjectAttrs{
18131814
Bucket: "Test",
18141815
Created: time.Date(2019, 3, 31, 19, 32, 10, 0, time.UTC),
1816+
Finalized: time.Date(2019, 3, 31, 19, 32, 10, 0, time.UTC),
18151817
ContentLanguage: "en-us",
18161818
ContentType: "video/mpeg",
18171819
CustomTime: time.Date(2020, 8, 25, 19, 33, 36, 0, time.UTC),
@@ -1843,6 +1845,7 @@ func TestObjectAttrsToRawObject(t *testing.T) {
18431845
in := &ObjectAttrs{
18441846
Bucket: "Test",
18451847
Created: time.Date(2019, 3, 31, 19, 32, 10, 0, time.UTC),
1848+
Finalized: time.Date(2019, 3, 31, 19, 32, 10, 0, time.UTC),
18461849
ContentLanguage: "en-us",
18471850
ContentType: "video/mpeg",
18481851
Deleted: time.Date(2019, 3, 31, 19, 33, 39, 0, time.UTC),
@@ -1893,13 +1896,15 @@ func TestProtoObjectToObjectAttrs(t *testing.T) {
18931896
RetentionExpireTime: timestamppb.New(now),
18941897
Size: 1 << 20,
18951898
CreateTime: timestamppb.New(now),
1899+
FinalizeTime: timestamppb.New(now),
18961900
DeleteTime: timestamppb.New(now),
18971901
TemporaryHold: true,
18981902
ComponentCount: 2,
18991903
},
19001904
want: &ObjectAttrs{
19011905
Bucket: "Test",
19021906
Created: now,
1907+
Finalized: now,
19031908
ContentLanguage: "en-us",
19041909
ContentType: "video/mpeg",
19051910
CustomTime: now,
@@ -1940,11 +1945,13 @@ func TestObjectAttrsToProtoObject(t *testing.T) {
19401945
RetentionExpireTime: timestamppb.New(now),
19411946
Size: 1 << 20,
19421947
CreateTime: timestamppb.New(now),
1948+
FinalizeTime: timestamppb.New(now),
19431949
DeleteTime: timestamppb.New(now),
19441950
TemporaryHold: true,
19451951
}
19461952
in := &ObjectAttrs{
19471953
Created: now,
1954+
Finalized: now,
19481955
ContentLanguage: "en-us",
19491956
ContentType: "video/mpeg",
19501957
CustomTime: now,

0 commit comments

Comments
 (0)