Files
objectstorage/test/test.s3-compat.test.ts

133 lines
3.9 KiB
TypeScript

import { assertEquals, assertExists } from 'jsr:@std/assert';
import { afterAll, beforeAll, describe, it } from 'jsr:@std/testing/bdd';
import {
S3Client,
ListBucketsCommand,
CreateBucketCommand,
DeleteBucketCommand,
PutObjectCommand,
GetObjectCommand,
ListObjectsV2Command,
CopyObjectCommand,
DeleteObjectCommand,
} from '@aws-sdk/client-s3';
import { createTestContainer, getTestPorts, TEST_ACCESS_KEY, TEST_SECRET_KEY } from './helpers/server.helper.ts';
import { ObjectStorageContainer } from '../ts/index.ts';
const PORT_INDEX = 4;
const ports = getTestPorts(PORT_INDEX);
const BUCKET = 's3-test-bucket';
describe('S3 SDK compatibility', { sanitizeResources: false, sanitizeOps: false }, () => {
let container: ObjectStorageContainer;
let s3: S3Client;
beforeAll(async () => {
container = createTestContainer(PORT_INDEX);
await container.start();
s3 = new S3Client({
endpoint: `http://localhost:${ports.objstPort}`,
region: 'us-east-1',
credentials: {
accessKeyId: TEST_ACCESS_KEY,
secretAccessKey: TEST_SECRET_KEY,
},
forcePathStyle: true,
});
});
afterAll(async () => {
s3.destroy();
await container.stop();
});
it('should list buckets (empty)', async () => {
const response = await s3.send(new ListBucketsCommand({}));
assertEquals((response.Buckets || []).length, 0);
});
it('should create bucket via S3', async () => {
await s3.send(new CreateBucketCommand({ Bucket: BUCKET }));
const response = await s3.send(new ListBucketsCommand({}));
const names = (response.Buckets || []).map((b) => b.Name);
assertEquals(names.includes(BUCKET), true);
});
it('should put object via S3', async () => {
await s3.send(
new PutObjectCommand({
Bucket: BUCKET,
Key: 'test.txt',
Body: new TextEncoder().encode('Hello from S3 SDK'),
ContentType: 'text/plain',
}),
);
});
it('should get object via S3', async () => {
const response = await s3.send(
new GetObjectCommand({ Bucket: BUCKET, Key: 'test.txt' }),
);
const body = await response.Body!.transformToString();
assertEquals(body, 'Hello from S3 SDK');
});
it('should list objects via S3', async () => {
const response = await s3.send(
new ListObjectsV2Command({ Bucket: BUCKET }),
);
const keys = (response.Contents || []).map((o) => o.Key);
assertEquals(keys.includes('test.txt'), true);
});
it('should copy object via S3', async () => {
await s3.send(
new CopyObjectCommand({
Bucket: BUCKET,
CopySource: `${BUCKET}/test.txt`,
Key: 'copy.txt',
}),
);
const response = await s3.send(
new GetObjectCommand({ Bucket: BUCKET, Key: 'copy.txt' }),
);
const body = await response.Body!.transformToString();
assertEquals(body, 'Hello from S3 SDK');
});
it('should delete object via S3', async () => {
await s3.send(new DeleteObjectCommand({ Bucket: BUCKET, Key: 'test.txt' }));
await s3.send(new DeleteObjectCommand({ Bucket: BUCKET, Key: 'copy.txt' }));
const response = await s3.send(
new ListObjectsV2Command({ Bucket: BUCKET }),
);
assertEquals((response.Contents || []).length, 0);
});
it('should reject requests with wrong credentials', async () => {
const badS3 = new S3Client({
endpoint: `http://localhost:${ports.objstPort}`,
region: 'us-east-1',
credentials: {
accessKeyId: 'wrongkey',
secretAccessKey: 'wrongsecret',
},
forcePathStyle: true,
});
let threw = false;
try {
await badS3.send(new ListBucketsCommand({}));
} catch {
threw = true;
}
badS3.destroy();
assertEquals(threw, true);
});
it('cleanup: delete bucket', async () => {
await s3.send(new DeleteBucketCommand({ Bucket: BUCKET }));
const response = await s3.send(new ListBucketsCommand({}));
assertEquals((response.Buckets || []).length, 0);
});
});