feat(test): add end-to-end test coverage for container lifecycle, auth, buckets, objects, policies, credentials, status, and S3 compatibility
This commit is contained in:
132
test/test.s3-compat.test.ts
Normal file
132
test/test.s3-compat.test.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user