Supported container runtimes
Azurite
登录后可跨设备保存划线和私人笔记登录
Azurite
Install
1npm install @testcontainers/azurite --save-devExamples
These examples use the following libraries:
-
1npm install @azure/data-tables -
1npm install @azure/storage-blob -
1npm install @azure/storage-queue
Choose an image from the container registry and substitute IMAGE.
Upload/download a blob
1
2
3
4
5
6
7
8
9
10
11
12
13
14await using container = await new AzuriteContainer(IMAGE).withSkipApiVersionCheck().start();
const connectionString = container.getConnectionString();
const serviceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = serviceClient.getContainerClient("test");
await containerClient.createIfNotExists();
const blobName = "hello.txt";
const content = "Hello world!";
await containerClient.uploadBlockBlob(blobName, content, Buffer.byteLength(content));
const blobClient = containerClient.getBlockBlobClient(blobName);
const downloadBuffer = await blobClient.downloadToBuffer();
expect(downloadBuffer.toString()).toBe(content);Send/receive queue messages
1
2
3
4
5
6
7
8
9
10
11
12
13await using container = await new AzuriteContainer(IMAGE).withSkipApiVersionCheck().start();
const connectionString = container.getConnectionString();
const serviceClient = QueueServiceClient.fromConnectionString(connectionString);
const queueName = "test-queue";
await serviceClient.createQueue(queueName);
const messageText = "Hello world!";
const queueClient = serviceClient.getQueueClient(queueName);
await queueClient.sendMessage(messageText);
const messages = await queueClient.receiveMessages();
expect(messages.receivedMessageItems).toMatchObject([{ messageText }]);Create/insert/fetch on a table
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18await using container = await new AzuriteContainer(IMAGE).withSkipApiVersionCheck().start();
const connectionString = container.getConnectionString();
const tableName = "person";
const tableClient = TableClient.fromConnectionString(connectionString, tableName, {
allowInsecureConnection: true,
});
await tableClient.createTable();
const entity: TableEntity<{ name: string }> = {
partitionKey: "p1",
rowKey: "r1",
name: "John Doe",
};
await tableClient.createEntity(entity);
const nextEntity = await tableClient.listEntities().next();
expect(nextEntity.value).toEqual(expect.objectContaining(entity));In memory persistence
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29await using container = await new AzuriteContainer(IMAGE)
.withSkipApiVersionCheck()
.withInMemoryPersistence()
.start();
const blobName = "hello.txt";
{
const connectionString = container.getConnectionString();
const serviceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = serviceClient.getContainerClient("test");
await containerClient.createIfNotExists();
const content = "Hello world!";
await containerClient.uploadBlockBlob(blobName, content, Buffer.byteLength(content));
const blobClient = containerClient.getBlockBlobClient(blobName);
const blobExists = await blobClient.exists();
expect(blobExists).toBeTruthy();
}
await container.restart();
{
const connectionString = container.getConnectionString();
const serviceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = serviceClient.getContainerClient("test");
const blobClient = containerClient.getBlockBlobClient(blobName);
const blobExistsAfterRestart = await blobClient.exists();
expect(blobExistsAfterRestart).toBeFalsy();
}With credentials
1
2
3
4
5
6
7
8
9
10
11const accountName = "test-account";
const accountKey = Buffer.from("test-key").toString("base64");
await using container = await new AzuriteContainer(IMAGE)
.withSkipApiVersionCheck()
.withAccountName(accountName)
.withAccountKey(accountKey)
.start();
const credentials = new StorageSharedKeyCredential(accountName, accountKey);
const serviceClient = new BlobServiceClient(container.getBlobEndpoint(), credentials);With ports
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const portGenerator = new RandomPortGenerator();
const blobPort = await portGenerator.generatePort();
const queuePort = await portGenerator.generatePort();
const tablePort = await portGenerator.generatePort();
await using container = await new AzuriteContainer(IMAGE)
.withSkipApiVersionCheck()
.withBlobPort({ container: 11000, host: blobPort })
.withQueuePort({ container: 11001, host: queuePort })
.withTablePort({ container: 11002, host: tablePort })
.start();
expect(container.getBlobPort()).toBe(blobPort);
expect(container.getQueuePort()).toBe(queuePort);
expect(container.getTablePort()).toBe(tablePort);With HTTPS (PEM certificate)
Codeazurite-test-utils
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17await using container = await new AzuriteContainer(IMAGE)
.withSkipApiVersionCheck()
.withSsl(TEST_CERT, TEST_KEY)
.start();
const connectionString = container.getConnectionString();
expect(connectionString).toContain("DefaultEndpointsProtocol=https");
expect(connectionString).toContain("BlobEndpoint=https://");
expect(connectionString).toContain("QueueEndpoint=https://");
expect(connectionString).toContain("TableEndpoint=https://");
const serviceClient = BlobServiceClient.fromConnectionString(connectionString, getTlsPipelineOptions(TEST_CERT));
const containerClient = serviceClient.getContainerClient("test");
await containerClient.createIfNotExists();
const containerItem = await serviceClient.listContainers().next();
expect(containerItem.value?.name).toBe("test"); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37type BlobClientPipelineOptions = NonNullable<Parameters<typeof BlobServiceClient.fromConnectionString>[1]>;
type BlobClientPipelineOptionsWithTls = BlobClientPipelineOptions & { tlsOptions: { ca: string } };
const base64UrlEncode = (value: string): string => Buffer.from(value).toString("base64url");
const createJwtToken = (payload: Record<string, string | number>): string => {
const header = { alg: "none", typ: "JWT" };
return `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}.`;
};
export const getTlsPipelineOptions = (ca: string): BlobClientPipelineOptionsWithTls => ({
tlsOptions: {
ca,
},
});
export const createOAuthToken = (audience: string): string => {
const now = Math.floor(Date.now() / 1000);
return createJwtToken({
nbf: now - 60,
iat: now - 60,
exp: now + 3600,
iss: "https://sts.windows.net/ab1f708d-50f6-404c-a006-d71b2ac7a606/",
aud: audience,
scp: "user_impersonation",
oid: "23657296-5cd5-45b0-a809-d972a7f4dfe1",
tid: "dd0d0df1-06c3-436c-8034-4b9a153097ce",
});
};
export const createTokenCredential = (token: string): TokenCredential => ({
getToken: async () => ({
token,
expiresOnTimestamp: Date.now() + 3600_000,
}),
});With OAuth (basic)
Codeazurite-test-utils
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22await using container = await new AzuriteContainer(IMAGE)
.withSkipApiVersionCheck()
.withSsl(TEST_CERT, TEST_KEY)
.withOAuth()
.start();
const validServiceClient = new BlobServiceClient(
container.getBlobEndpoint(),
createTokenCredential(createOAuthToken("https://storage.azure.com")),
getTlsPipelineOptions(TEST_CERT)
);
const validContainerClient = validServiceClient.getContainerClient(`oauth-valid-${Date.now()}`);
await validContainerClient.create();
await validContainerClient.delete();
const invalidServiceClient = new BlobServiceClient(
container.getBlobEndpoint(),
createTokenCredential(createOAuthToken("https://invalidaccount.blob.core.windows.net")),
getTlsPipelineOptions(TEST_CERT)
);
const invalidContainerClient = invalidServiceClient.getContainerClient(`oauth-invalid-${Date.now()}`);
await expect(invalidContainerClient.create()).rejects.toThrow("Server failed to authenticate the request"); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37type BlobClientPipelineOptions = NonNullable<Parameters<typeof BlobServiceClient.fromConnectionString>[1]>;
type BlobClientPipelineOptionsWithTls = BlobClientPipelineOptions & { tlsOptions: { ca: string } };
const base64UrlEncode = (value: string): string => Buffer.from(value).toString("base64url");
const createJwtToken = (payload: Record<string, string | number>): string => {
const header = { alg: "none", typ: "JWT" };
return `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}.`;
};
export const getTlsPipelineOptions = (ca: string): BlobClientPipelineOptionsWithTls => ({
tlsOptions: {
ca,
},
});
export const createOAuthToken = (audience: string): string => {
const now = Math.floor(Date.now() / 1000);
return createJwtToken({
nbf: now - 60,
iat: now - 60,
exp: now + 3600,
iss: "https://sts.windows.net/ab1f708d-50f6-404c-a006-d71b2ac7a606/",
aud: audience,
scp: "user_impersonation",
oid: "23657296-5cd5-45b0-a809-d972a7f4dfe1",
tid: "dd0d0df1-06c3-436c-8034-4b9a153097ce",
});
};
export const createTokenCredential = (token: string): TokenCredential => ({
getToken: async () => ({
token,
expiresOnTimestamp: Date.now() + 3600_000,
}),
});评论
登录后参与评论
正在加载评论…
KnowForge