mirror of
https://github.com/minio/minio.git
synced 2025-04-30 14:47:10 -04:00
fix: immediate tiering for NoncurrentVersionTransition (#13464)
This commit is contained in:
parent
221ef78faa
commit
45d145a823
@ -316,10 +316,9 @@ func (lc Lifecycle) ComputeAction(obj ObjectOpts) Action {
|
|||||||
if obj.VersionID != "" && !obj.IsLatest && !obj.SuccessorModTime.IsZero() && !obj.DeleteMarker && obj.TransitionStatus != TransitionComplete {
|
if obj.VersionID != "" && !obj.IsLatest && !obj.SuccessorModTime.IsZero() && !obj.DeleteMarker && obj.TransitionStatus != TransitionComplete {
|
||||||
// Non current versions should be transitioned if their age exceeds non current days configuration
|
// Non current versions should be transitioned if their age exceeds non current days configuration
|
||||||
// https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#intro-lifecycle-rules-actions
|
// https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html#intro-lifecycle-rules-actions
|
||||||
if time.Now().After(ExpectedExpiryTime(obj.SuccessorModTime, int(rule.NoncurrentVersionTransition.NoncurrentDays))) {
|
if due, ok := rule.NoncurrentVersionTransition.NextDue(obj); ok && time.Now().UTC().After(due) {
|
||||||
return TransitionVersionAction
|
return TransitionVersionAction
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
xhttp "github.com/minio/minio/internal/http"
|
xhttp "github.com/minio/minio/internal/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -216,12 +217,15 @@ func TestExpectedExpiryTime(t *testing.T) {
|
|||||||
|
|
||||||
func TestComputeActions(t *testing.T) {
|
func TestComputeActions(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
inputConfig string
|
inputConfig string
|
||||||
objectName string
|
objectName string
|
||||||
objectTags string
|
objectTags string
|
||||||
objectModTime time.Time
|
objectModTime time.Time
|
||||||
isExpiredDelMarker bool
|
isExpiredDelMarker bool
|
||||||
expectedAction Action
|
expectedAction Action
|
||||||
|
isNoncurrent bool
|
||||||
|
objectSuccessorModTime time.Time
|
||||||
|
versionID string
|
||||||
}{
|
}{
|
||||||
// Empty object name (unexpected case) should always return NoneAction
|
// Empty object name (unexpected case) should always return NoneAction
|
||||||
{
|
{
|
||||||
@ -386,13 +390,23 @@ func TestComputeActions(t *testing.T) {
|
|||||||
isExpiredDelMarker: true,
|
isExpiredDelMarker: true,
|
||||||
expectedAction: DeleteVersionAction,
|
expectedAction: DeleteVersionAction,
|
||||||
},
|
},
|
||||||
// Should not delete expired marker if its time has not come yet
|
// Should transition immediately when Transition days is zero
|
||||||
{
|
{
|
||||||
inputConfig: `<BucketLifecycleConfiguration><Rule><Filter></Filter><Status>Enabled</Status><Transition><Days>0</Days><StorageClass>S3TIER-1</StorageClass></Transition></Rule></BucketLifecycleConfiguration>`,
|
inputConfig: `<BucketLifecycleConfiguration><Rule><Filter></Filter><Status>Enabled</Status><Transition><Days>0</Days><StorageClass>S3TIER-1</StorageClass></Transition></Rule></BucketLifecycleConfiguration>`,
|
||||||
objectName: "foodir/fooobject",
|
objectName: "foodir/fooobject",
|
||||||
objectModTime: time.Now().UTC(), // Created now
|
objectModTime: time.Now().UTC(), // Created now
|
||||||
expectedAction: TransitionAction,
|
expectedAction: TransitionAction,
|
||||||
},
|
},
|
||||||
|
// Should transition immediately when NoncurrentVersion Transition days is zero
|
||||||
|
{
|
||||||
|
inputConfig: `<BucketLifecycleConfiguration><Rule><Filter></Filter><Status>Enabled</Status><NoncurrentVersionTransition><NoncurrentDays>0</NoncurrentDays><StorageClass>S3TIER-1</StorageClass></NoncurrentVersionTransition></Rule></BucketLifecycleConfiguration>`,
|
||||||
|
objectName: "foodir/fooobject",
|
||||||
|
objectModTime: time.Now().UTC(), // Created now
|
||||||
|
expectedAction: TransitionVersionAction,
|
||||||
|
isNoncurrent: true,
|
||||||
|
objectSuccessorModTime: time.Now().UTC(),
|
||||||
|
versionID: uuid.New().String(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
@ -403,12 +417,14 @@ func TestComputeActions(t *testing.T) {
|
|||||||
t.Fatalf("Got unexpected error: %v", err)
|
t.Fatalf("Got unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if resultAction := lc.ComputeAction(ObjectOpts{
|
if resultAction := lc.ComputeAction(ObjectOpts{
|
||||||
Name: tc.objectName,
|
Name: tc.objectName,
|
||||||
UserTags: tc.objectTags,
|
UserTags: tc.objectTags,
|
||||||
ModTime: tc.objectModTime,
|
ModTime: tc.objectModTime,
|
||||||
DeleteMarker: tc.isExpiredDelMarker,
|
DeleteMarker: tc.isExpiredDelMarker,
|
||||||
NumVersions: 1,
|
NumVersions: 1,
|
||||||
IsLatest: true,
|
IsLatest: !tc.isNoncurrent,
|
||||||
|
SuccessorModTime: tc.objectSuccessorModTime,
|
||||||
|
VersionID: tc.versionID,
|
||||||
}); resultAction != tc.expectedAction {
|
}); resultAction != tc.expectedAction {
|
||||||
t.Fatalf("Expected action: `%v`, got: `%v`", tc.expectedAction, resultAction)
|
t.Fatalf("Expected action: `%v`, got: `%v`", tc.expectedAction, resultAction)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user