Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 20 additions & 24 deletions extensions/lifecycle/tasks/LifecycleTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -813,18 +813,18 @@ class LifecycleTask extends BackbeatTask {
/**
* check if rule applies for a given date or calculed days.
* @param {array} rule - bucket lifecycle rule
* @param {number} daysSinceInitiated - Days passed since entity (object or version) last modified
* @param {string} lastModified - entity (object or version) last modified date
* NOTE: entity is not an in-progress MPU or a delete marker.
* @param {number} currentDate - current date
* @return {boolean} true if rule applies - false otherwise.
*/
_isRuleApplying(rule, daysSinceInitiated, currentDate) {
_isRuleApplying(rule, lastModified) {
if (rule.Expiration && this._supportedRules.includes('Expiration')) {
if (rule.Expiration.Days !== undefined && daysSinceInitiated >= rule.Expiration.Days) {
if (rule.Expiration.Days !== undefined &&
this._lifecycleDateTime.findDaysSince(new Date(lastModified)) >= rule.Expiration.Days) {
Comment thread
maeldonn marked this conversation as resolved.
return true;
}

if (rule.Expiration.Date && rule.Expiration.Date < currentDate) {
if (rule.Expiration.Date && rule.Expiration.Date < this._lifecycleDateTime.getCurrentDate()) {
return true;
}
// Expiration.ExpiredObjectDeleteMarker rule's action does not apply
Expand All @@ -835,14 +835,10 @@ class LifecycleTask extends BackbeatTask {

if (rule.Transitions && rule.Transitions.length > 0
&& this._supportedRules.includes('Transition')) {
// getCurrentDate() is shifted by expireOneDayEarlier: transitions use the real clock.
return rule.Transitions.some(t => {
if (t.Days !== undefined && daysSinceInitiated >= t.Days) {
return true;
}
if (t.Date && t.Date < currentDate) {
return true;
}
return false;
const transitionTime = this._lifecycleDateTime.getTransitionTimestamp(t, lastModified);
return transitionTime !== null && transitionTime <= Date.now();
});
}

Expand All @@ -860,10 +856,6 @@ class LifecycleTask extends BackbeatTask {
* @return {boolean} true if eligible - false otherwise.
*/
_isEntityEligible(rules, entity, versioningStatus) {
const currentDate = this._lifecycleDateTime.getCurrentDate();
const daysSinceInitiated = this._lifecycleDateTime.findDaysSince(
new Date(entity.LastModified)
);
const { staleDate } = entity;
const daysSinceStaled = staleDate ?
this._lifecycleDateTime.findDaysSince(new Date(staleDate)) : null;
Expand All @@ -881,7 +873,7 @@ class LifecycleTask extends BackbeatTask {

if (versioningStatus === 'Enabled' || versioningStatus === 'Suspended') {
if (entity.IsLatest) {
return this._isRuleApplying(rule, daysSinceInitiated, currentDate);
return this._isRuleApplying(rule, entity.LastModified);
}

if (!staleDate) {
Expand All @@ -900,14 +892,17 @@ class LifecycleTask extends BackbeatTask {

if (rule.NoncurrentVersionTransitions && rule.NoncurrentVersionTransitions.length > 0
&& this._supportedRules.includes('NoncurrentVersionTransition')) {
return rule.NoncurrentVersionTransitions.some(t =>
(t.NoncurrentDays !== undefined && daysSinceInitiated >= t.NoncurrentDays));
return rule.NoncurrentVersionTransitions.some(t => {
const transitionTime = this._lifecycleDateTime
.getNCVTransitionTimestamp(t, staleDate);
return transitionTime !== undefined && transitionTime <= Date.now();
});
}

return false;
}

return this._isRuleApplying(rule, daysSinceInitiated, currentDate);
return this._isRuleApplying(rule, entity.LastModified);
});
}

Expand Down Expand Up @@ -1356,12 +1351,13 @@ class LifecycleTask extends BackbeatTask {
*/
_checkAndApplyNCVTransitionRule(bucketData, version, rules, log, cb) {
const staleDate = version.staleDate;
const daysSinceInitiated = this._lifecycleDateTime.findDaysSince(new Date(staleDate));
const ncvt = 'NoncurrentVersionTransition';
const ncd = 'NoncurrentDays';
const doesNCVTransitionRuleApply = (rules[ncvt] &&
rules[ncvt][ncd] !== undefined &&
daysSinceInitiated >= rules[ncvt][ncd]);
const ncvTransitionTime = rules[ncvt] && rules[ncvt][ncd] !== undefined ?
this._lifecycleDateTime.getNCVTransitionTimestamp(rules[ncvt], staleDate) :
undefined;
const doesNCVTransitionRuleApply = ncvTransitionTime !== undefined &&
ncvTransitionTime <= Date.now();

if (doesNCVTransitionRuleApply) {
this._applyTransitionRule({
Expand Down
70 changes: 70 additions & 0 deletions tests/unit/lifecycle/LifecycleTask.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,76 @@ describe('lifecycle task helper methods', () => {
});
});

describe('transitions with one day earlier flags', () => {
const bucketData = { target: { owner: 'o', accountId: 'a', bucket: 'b' } };
const transitionRules = [{
ID: 'id1',
Prefix: '',
Status: 'Enabled',
Transitions: [{ Days: 1, StorageClass: 'cold' }],
NoncurrentVersionTransitions: [],
}];
const ncvTransitionRules = [{
ID: 'id1',
Prefix: '',
Status: 'Enabled',
Transitions: [],
NoncurrentVersionTransitions: [{ NoncurrentDays: 1, StorageClass: 'cold' }],
}];
const applicableNCVRules = {
NoncurrentVersionTransition: { NoncurrentDays: 1, StorageClass: 'cold' },
};

const makeTask = flags => new LifecycleTask({
getStateVars: () => ({
ncvHeap: new Map(),
lcOptions: { ...timeOptions, ...flags },
log: fakeLogger,
supportedRules: ValidLifecycleRules,
}),
});

const isNCVTransitionApplied = (task, version) => {
const applyStub = sinon.stub(task, '_applyTransitionRule').callsFake((params, log, cb) => cb());
task._checkAndApplyNCVTransitionRule(bucketData, version, applicableNCVRules, fakeLogger, () => {});
return applyStub.calledOnce;
};

[
{ flags: {}, expected: false },
{ flags: { transitionOneDayEarlier: true }, expected: true },
{ flags: { expireOneDayEarlier: true }, expected: false },
].forEach(({ flags, expected }) => {
const desc = JSON.stringify(flags);

it(`should ${expected ? '' : 'not '}find 1 day transition eligible on 1 hour old object with ${desc}`,
() => {
const object = { ...OBJECT, LastModified: new Date(Date.now() - HOUR).toISOString() };
assert.strictEqual(makeTask(flags)._isEntityEligible(transitionRules, object, 'Disabled'), expected);
});

it(`should ${expected ? '' : 'not '}find 1 day ncv transition eligible on 1 hour old version with ${desc}`,
() => {
const version = {
...NON_CURRENT_VERSION,
LastModified: new Date(Date.now() - 2 * DAY).toISOString(),
staleDate: new Date(Date.now() - HOUR).toISOString(),
};
assert.strictEqual(makeTask(flags)._isEntityEligible(ncvTransitionRules, version, 'Enabled'), expected);
});

it(`should ${expected ? '' : 'not '}apply 1 day ncv transition on 1 hour stale version with ${desc}`,
() => {
const version = {
...NON_CURRENT_VERSION,
LastModified: new Date(Date.now() - 2 * DAY).toISOString(),
staleDate: new Date(Date.now() - HOUR).toISOString(),
};
assert.strictEqual(isNCVTransitionApplied(makeTask(flags), version), expected);
});
});
});

describe('_checkAndApplyNCVExpirationRule', () => {
let lct2;

Expand Down
Loading