Skip to content
Merged
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"engines": {
"node": ">=22"
},
"version": "8.2.6",
"version": "8.3.0",
"description": "API for tracking resource utilization and reporting metrics",
"main": "index.js",
"repository": {
Expand All @@ -19,7 +19,7 @@
"dependencies": {
"@hapi/joi": "^17.1.1",
"@senx/warp10": "1.0.14",
"arsenal": "git+https://github.com/scality/Arsenal#8.2.28",
"arsenal": "git+https://github.com/scality/Arsenal#8.5.6",
"async": "^3.2.6",
"aws-sdk": "^2.1005.0",
"aws4": "^1.13.2",
Expand Down
111 changes: 111 additions & 0 deletions tests/unit/v2/testMetadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const assert = require('assert');
const sinon = require('sinon');

const { errors } = require('arsenal');
const { BucketInfo } = require('arsenal').models;
const client = require('../../../libV2/metadata/client');
const metadata = require('../../../libV2/metadata');

function bucketMD(replicationConfiguration) {
return new BucketInfo(
'test-bucket', 'test-canonical-id', 'test-owner', '2026-01-01T00:00:00.000Z',
undefined, undefined, undefined, undefined, undefined, undefined,
undefined, undefined, undefined, replicationConfiguration,
).serialize();
}

const v1ReplicationConfig = {
role: 'arn:aws:iam::123:role/src,arn:aws:iam::123:role/dst',
destination: 'arn:aws:s3:::dest-bucket',
rules: [{
id: 'rule-1', prefix: '', enabled: true, storageClass: 'site2',
}],
};

const v2ReplicationConfig = {
role: 'arn:aws:iam::123:role/src,arn:aws:iam::123:role/dst',
rules: [{
id: 'rule-1', enabled: true, storageClass: 'site2', destination: 'arn:aws:s3:::dest-bucket',
}],
format: 'v2',
};

describe('Test metadata client', () => {
let getBucketAttributesStub;

beforeEach(() => {
getBucketAttributesStub = sinon.stub(client.client, 'getBucketAttributes');
});

afterEach(() => sinon.restore());

function respondWith(err, data) {
getBucketAttributesStub.callsFake((_bucket, _uids, cb) => cb(err, data));
}

describe('getBucket', () => {
it('should parse bucket metadata with a V1 replication configuration', async () => {
respondWith(null, bucketMD(v1ReplicationConfig));
const bucket = await metadata.getBucket('test-bucket');
assert.strictEqual(bucket.getOwner(), 'test-canonical-id');
assert.strictEqual(bucket.getReplicationConfiguration().destination, 'arn:aws:s3:::dest-bucket');
});

it('should parse bucket metadata with a V2 replication configuration', async () => {
respondWith(null, bucketMD(v2ReplicationConfig));
const bucket = await metadata.getBucket('test-bucket');
assert.strictEqual(bucket.getOwner(), 'test-canonical-id');
assert.strictEqual(bucket.getReplicationConfiguration().rules[0].destination, 'arn:aws:s3:::dest-bucket');
});

it('should parse a multi-destination (multi-CRR) V2 replication configuration', async () => {
const config = {
...v2ReplicationConfig,
rules: [
{
id: 'rule-1', enabled: true, storageClass: 'site2', destination: 'arn:aws:s3:::dest-1',
},
{
id: 'rule-2', enabled: true, prefix: 'foo/', storageClass: 'site3',
destination: 'arn:aws:s3:::dest-2', account: '123456789012',
},
],
};
respondWith(null, bucketMD(config));
const bucket = await metadata.getBucket('test-bucket');
assert.strictEqual(bucket.getOwner(), 'test-canonical-id');
const replication = bucket.getReplicationConfiguration();
assert.strictEqual(replication.destination, undefined);
assert.deepStrictEqual(replication.rules.map(rule => rule.destination),
['arn:aws:s3:::dest-1', 'arn:aws:s3:::dest-2']);
});

it('should parse bucket metadata without a replication configuration', async () => {
respondWith(null, bucketMD(undefined));
const bucket = await metadata.getBucket('test-bucket');
assert.strictEqual(bucket.getOwner(), 'test-canonical-id');
});

it('should reject on client error', async () => {
respondWith(errors.InternalError, null);
await assert.rejects(metadata.getBucket('test-bucket'), err => err.is.InternalError);
});
});

describe('bucketExists', () => {
it('should resolve true when the bucket exists', async () => {
respondWith(null, bucketMD(v2ReplicationConfig));
assert.strictEqual(await metadata.bucketExists('test-bucket'), true);
});

it('should resolve false when the bucket does not exist', async () => {
respondWith(errors.NoSuchBucket, null);
assert.strictEqual(await metadata.bucketExists('test-bucket'), false);
});

it('should reject on other errors', async () => {
respondWith(errors.InternalError, null);
await assert.rejects(metadata.bucketExists('test-bucket'), err => err.is.InternalError);
});
});
});
Loading
Loading