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
6 changes: 3 additions & 3 deletions solution/deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ backbeat:
dashboard: backbeat/backbeat-dashboards
image: backbeat
policy: backbeat/backbeat-policies
tag: 9.5.0-preview.1
tag: 9.5.0-preview.4
envsubst: BACKBEAT_TAG
busybox:
image: busybox
Expand All @@ -16,7 +16,7 @@ cloudserver:
sourceRegistry: ghcr.io/scality
dashboard: cloudserver/cloudserver-dashboards
image: cloudserver
tag: 9.4.0-preview.2
tag: 9.4.0-preview.4
envsubst: CLOUDSERVER_TAG
drctl:
sourceRegistry: ghcr.io/scality
Expand Down Expand Up @@ -80,7 +80,7 @@ mongodb-connector:
pensieve-api:
sourceRegistry: ghcr.io/scality
image: pensieve-api
tag: 1.10.1
tag: 1.11.0-preview.1
envsubst: PENSIEVE_API_TAG
rclone:
sourceRegistry: rclone
Expand Down
17 changes: 17 additions & 0 deletions tests/functional/ctst/features/lifecycleExpiration.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Feature: Lifecycle expiration

@2.16.0
@PreMerge
@Expiration
@Lifecycle
Scenario Outline: Days=0 expiration empties a "<versioningConfiguration>" bucket
Given a "<versioningConfiguration>" bucket
And 5 objects "expire-obj" of size 100 bytes
When i set a lifecycle expiration of 0 days for the "<scope>"
Then the bucket should contain 0 objects within 180 seconds

Examples:
| versioningConfiguration | scope |
| Non versioned | current version |
| Versioned | current and noncurrent versions |
| Suspended | current and noncurrent versions |
39 changes: 39 additions & 0 deletions tests/functional/ctst/steps/lifecycleExpiration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Then, When } from '@cucumber/cucumber';
import { S3, Utils } from 'cli-testing';
import { ListObjectVersionsOutput } from '@aws-sdk/client-s3';
import assert from 'assert';
import Zenko from 'world/Zenko';
import { safeJsonParse } from 'common/utils';
import { addExpirationWorkflow } from './utils/utils';

When('i set a lifecycle expiration of {int} days for the {string}',
async function (this: Zenko, days: number, scope: string) {
const includeNoncurrent: Record<string, boolean> = {
'current version': false,
'current and noncurrent versions': true,
};
assert(scope in includeNoncurrent, `Unknown expiration scope "${scope}"`);
await addExpirationWorkflow.call(this, days, includeNoncurrent[scope]);
});

Then('the bucket should contain {int} objects within {int} seconds', { timeout: 6 * 60 * 1000 },
async function (this: Zenko, expectedCount: number, seconds: number) {
const bucketName = this.getSaved<string>('bucketName');
const deadline = Date.now() + seconds * 1000;
let count = -1;
do {
const res = await S3.listObjectVersions({ bucket: bucketName, maxItems: '1000' });
const parsed = safeJsonParse<ListObjectVersionsOutput>(res.stdout || '{}');
assert.ok(parsed.ok, `Failed to list versions in bucket ${bucketName}: ${parsed.error}`);
const versions = parsed.result?.Versions ?? [];
const deleteMarkers = parsed.result?.DeleteMarkers ?? [];
count = versions.length + deleteMarkers.length;
if (count === expectedCount) {
return;
}
await Utils.sleep(2000);
} while (Date.now() < deadline);
assert.fail(
`Bucket ${bucketName} has ${count} versions/delete markers, ` +
`expected ${expectedCount} after ${seconds}s`);
});
66 changes: 42 additions & 24 deletions tests/functional/ctst/steps/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,35 +378,52 @@ async function emptyVersionedBucket(world: Zenko) {
}));
}

async function addTransitionWorkflow(this: Zenko, location: string, enabled = true) {
let conditionOk = false;
this.resetCommand();
this.addCommandParameter({ bucket: this.getSaved<string>('bucketName') });
const enabledStr = enabled ? 'Enabled' : 'Disabled';
const lifecycleConfiguration = JSON.stringify({
Rules: [
{
Status: enabledStr,
Prefix: '',
Transitions: [
{
Days: 0,
StorageClass: location,
},
],
},
],
});
this.addCommandParameter({
lifecycleConfiguration,
async function putBucketLifecycleConfigurationWithRetry(world: Zenko, rules: Record<string, unknown>[]) {
world.resetCommand();
world.addCommandParameter({ bucket: world.getSaved<string>('bucketName') });
world.addCommandParameter({
lifecycleConfiguration: JSON.stringify({ Rules: rules }),
});
const commandParameters = this.getCommandParameters();
const commandParameters = world.getCommandParameters();
let conditionOk = false;
while (!conditionOk) {
const res = await S3.putBucketLifecycleConfiguration(commandParameters);
conditionOk = res.err === null;
// Wait for the transition to be accepted because the deployment of the location's pods can take some time
await Utils.sleep(5000);
// Wait for the configuration to be accepted because the deployment of the location's pods can take some time
await Utils.sleep(5000);
}
}

async function addTransitionWorkflow(this: Zenko, location: string, enabled = true) {
const enabledStr = enabled ? 'Enabled' : 'Disabled';
await putBucketLifecycleConfigurationWithRetry(this, [
{
Status: enabledStr,
Prefix: '',
Transitions: [
{
Days: 0,
StorageClass: location,
},
],
},
]);
}

async function addExpirationWorkflow(this: Zenko, days: number, includeNoncurrentVersions = false) {
const rule: Record<string, unknown> = {
Status: 'Enabled',
Prefix: '',
Expiration: {
Days: days,
},
};
if (includeNoncurrentVersions) {
rule.NoncurrentVersionExpiration = {
NoncurrentDays: days,
};
}
await putBucketLifecycleConfigurationWithRetry(this, [rule]);
}

async function getReplicationLocationConfig(world: Zenko, location: string): Promise<{
Expand Down Expand Up @@ -601,6 +618,7 @@ export {
getObjectNameWithBackendFlakiness,
restoreObject,
addTransitionWorkflow,
addExpirationWorkflow,
getReplicationLocationConfig,
putBucketReplication,
};
2 changes: 1 addition & 1 deletion tests/functional/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"async": "2.1.2",
"aws4": "^1.11.0",
"aws4-axios": "^3.3.8",
"cli-testing": "git+https://github.com/scality/cli-testing.git#v1.3.0",
"cli-testing": "git+https://github.com/scality/cli-testing.git#v1.3.1",
"js-yaml": "^4.2.0",
"mocha": "^11.7.5",
"mocha-junit-reporter": "^2.2.1",
Expand Down
6 changes: 3 additions & 3 deletions tests/functional/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2511,9 +2511,9 @@ cli-table3@0.6.5:
optionalDependencies:
"@colors/colors" "1.5.0"

"cli-testing@git+https://github.com/scality/cli-testing.git#v1.3.0":
version "1.3.0"
resolved "git+https://github.com/scality/cli-testing.git#a4516ed463c766440e16d5bc52ff9c6b9222edce"
"cli-testing@git+https://github.com/scality/cli-testing.git#v1.3.1":
version "1.3.1"
resolved "git+https://github.com/scality/cli-testing.git#a53395ca89d16c7b0995249f5c84002678896377"
dependencies:
"@aws-crypto/sha256-universal" "^5.2.0"
"@aws-sdk/client-iam" "^3.879.0"
Expand Down
Loading