Skip to content

Commit 6a55cc9

Browse files
Refactoring, more tests, and PR comment
1 parent f353d11 commit 6a55cc9

File tree

6 files changed

+101
-108
lines changed

6 files changed

+101
-108
lines changed

docs/modules/azureservicebus.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,9 @@ Choose an image from the [container registry](https://hub.docker.com/r/microsoft
2727
<!--codeinclude-->
2828
[](../../packages/modules/azureservicebus/src/azureservicebus-container.test.ts) inside_block:serviceBusValidEmulatorConfig
2929
<!--/codeinclude-->
30+
31+
### Customize the MS SQL container
32+
33+
<!--codeinclude-->
34+
[](../../packages/modules/azureservicebus/src/azureservicebus-container.test.ts) inside_block:serviceBusCustomMssqlContainer
35+
<!--/codeinclude-->

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@
4545
},
4646
"engines": {
4747
"node": ">= 20"
48-
}
48+
},
49+
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
4950
}

packages/modules/azureservicebus/src/azureservicebus-container.test.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ServiceBusClient } from "@azure/service-bus";
2+
import { GenericContainer, Wait } from "testcontainers";
23
import { getImage } from "../../../testcontainers/src/utils/test-helper";
34
import { ServiceBusContainer } from "./azureservicebus-container";
45

@@ -8,11 +9,18 @@ describe("ServiceBuscontainer", { timeout: 180_000 }, () => {
89
it("should connect and queue a message", async () => {
910
// serviceBusConnect {
1011
await using container = await new ServiceBusContainer(IMAGE).acceptLicense().start();
12+
1113
const client = new ServiceBusClient(container.getConnectionString());
1214
const sender = client.createSender("queue.1");
15+
const reciever = client.createReceiver("queue.1");
1316

1417
await sender.sendMessages({ body: "Hello, World!" });
18+
const res = await reciever.receiveMessages(1, { maxWaitTimeInMs: 5_000 });
19+
20+
expect(res).toHaveLength(1);
21+
expect(res[0].body).toBe("Hello, World!");
1522

23+
await reciever.close();
1624
await sender.close();
1725
await client.close();
1826
// }
@@ -52,13 +60,67 @@ describe("ServiceBuscontainer", { timeout: 180_000 }, () => {
5260
});
5361

5462
await using container = await new ServiceBusContainer(IMAGE).acceptLicense().withConfig(config).start();
63+
5564
const client = new ServiceBusClient(container.getConnectionString());
5665
const sender = client.createSender(queueName);
66+
const reciever = client.createReceiver(queueName);
5767
// }
5868

5969
await sender.sendMessages({ body: "Hello, World!" });
70+
const res = await reciever.receiveMessages(1, { maxWaitTimeInMs: 5_000 });
6071

72+
expect(res).toHaveLength(1);
73+
expect(res[0].body).toBe("Hello, World!");
74+
75+
await reciever.close();
6176
await sender.close();
6277
await client.close();
6378
});
79+
80+
it("should connect with a custom MSSQL container", async () => {
81+
// serviceBusCustomMssqlContainer {
82+
// You are responsible for configuring the SA password on
83+
// BOTH containers when using a custom MSSQL container.
84+
const customPassword = "MyC0mplexP@ssw0rd!";
85+
86+
// @testcontainers/mssqlserver can be used as well
87+
const mssqlContainer = new GenericContainer("mcr.microsoft.com/mssql/server:2022-latest")
88+
.withEnvironment({
89+
ACCEPT_EULA: "Y",
90+
MSSQL_SA_PASSWORD: customPassword,
91+
})
92+
.withWaitStrategy(Wait.forLogMessage(/.*Recovery is complete.*/, 1).withStartupTimeout(120_000));
93+
94+
await using container = await new ServiceBusContainer(IMAGE)
95+
.acceptLicense()
96+
.withMssqlContainer(mssqlContainer)
97+
.withMssqlPassword(customPassword)
98+
.start();
99+
100+
const client = new ServiceBusClient(container.getConnectionString());
101+
// }
102+
103+
const sender = client.createSender("queue.1");
104+
const reciever = client.createReceiver("queue.1");
105+
106+
await sender.sendMessages({ body: "Hello, World!" });
107+
const res = await reciever.receiveMessages(1, { maxWaitTimeInMs: 5_000 });
108+
109+
expect(res).toHaveLength(1);
110+
expect(res[0].body).toBe("Hello, World!");
111+
112+
await reciever.close();
113+
await sender.close();
114+
await client.close();
115+
});
116+
117+
it("should connect containers to the same network", async () => {
118+
await using serviceBusContainer = await new ServiceBusContainer(IMAGE).acceptLicense().start();
119+
120+
const servicebusNetworks = serviceBusContainer.getNetworkNames();
121+
const mssqlNetworks = serviceBusContainer.getMssqlContainer().getNetworkNames();
122+
123+
expect(servicebusNetworks).toHaveLength(1);
124+
expect(mssqlNetworks).toEqual(expect.arrayContaining(servicebusNetworks));
125+
});
64126
});

packages/modules/azureservicebus/src/azureservicebus-container.ts

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@ import {
66
StartedTestContainer,
77
Wait,
88
} from "testcontainers";
9-
import { MSSQLServerContainer, StartedMSSQLServerContainer } from "./mssqlserver";
109

1110
const DEFAULT_PORT = 5672;
1211
const DEFAULT_HTTP_PORT = 5300;
1312
const DEFAULT_SHARED_ACCESS_KEY_NAME = "RootManageSharedAccessKey";
1413
const DEFAULT_SHARED_ACCESS_KEY = "SAS_KEY_VALUE";
1514
const DEFAULT_MSSQL_ALIAS = "mssql";
1615
const DEFAULT_MSSQL_IMAGE = "mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04";
16+
const DEFAULT_MSSQL_PASSWORD = "P@ssword1!";
1717
const CONTAINER_CONFIG_FILE = "/ServiceBus_Emulator/ConfigFiles/Config.json";
1818

1919
export class ServiceBusContainer extends GenericContainer {
2020
private acceptEula: string = "N";
21-
private mssqlContainer: MSSQLServerContainer | undefined;
21+
private mssqlContainer: GenericContainer | undefined;
2222
private mssqlImage: string = DEFAULT_MSSQL_IMAGE;
23+
private mssqlPassword: string = DEFAULT_MSSQL_PASSWORD;
2324
private config: Content | undefined;
2425

2526
constructor(image: string) {
@@ -37,7 +38,7 @@ export class ServiceBusContainer extends GenericContainer {
3738
return this;
3839
}
3940

40-
public withMssqlContainer(container: MSSQLServerContainer): this {
41+
public withMssqlContainer(container: GenericContainer): this {
4142
this.mssqlContainer = container;
4243
return this;
4344
}
@@ -47,34 +48,37 @@ export class ServiceBusContainer extends GenericContainer {
4748
return this;
4849
}
4950

51+
public withMssqlPassword(password: string): this {
52+
this.mssqlPassword = password;
53+
return this;
54+
}
55+
5056
public withConfig(config: Content): this {
5157
this.config = config;
5258
return this;
5359
}
5460

5561
public override async start(): Promise<StartedServiceBusContainer> {
56-
let mssql: StartedMSSQLServerContainer;
57-
58-
if (this.mssqlContainer) {
59-
mssql = await this.mssqlContainer.start();
60-
} else {
61-
const network = await new Network().start();
62-
const alias = DEFAULT_MSSQL_ALIAS;
63-
64-
this.mssqlContainer = new MSSQLServerContainer(this.mssqlImage)
65-
.withNetwork(network)
66-
.withNetworkAliases(alias)
67-
.acceptLicense();
68-
69-
mssql = await this.mssqlContainer.start();
70-
71-
this.withNetwork(network);
72-
this.withEnvironment({
73-
SQL_SERVER: alias,
74-
MSSQL_SA_PASSWORD: mssql.getPassword(),
75-
});
62+
let mssql: StartedTestContainer;
63+
64+
const network = await new Network().start();
65+
this.withNetwork(network);
66+
67+
if (!this.mssqlContainer) {
68+
// This should match the behaviour of @testcontainers/mssqlserver, we
69+
// create the container manually here to avoid module dependencies.
70+
this.mssqlContainer = new GenericContainer(this.mssqlImage)
71+
.withNetworkAliases(DEFAULT_MSSQL_ALIAS)
72+
.withEnvironment({
73+
ACCEPT_EULA: "Y",
74+
MSSQL_SA_PASSWORD: this.mssqlPassword,
75+
})
76+
.withExposedPorts(1433)
77+
.withWaitStrategy(Wait.forLogMessage(/.*Recovery is complete.*/, 1).withStartupTimeout(120_000));
7678
}
7779

80+
mssql = await this.mssqlContainer.withNetwork(network).start();
81+
7882
if (this.config) {
7983
this.withCopyContentToContainer([
8084
{
@@ -87,6 +91,8 @@ export class ServiceBusContainer extends GenericContainer {
8791

8892
this.withEnvironment({
8993
ACCEPT_EULA: this.acceptEula,
94+
SQL_SERVER: mssql.getHostname(),
95+
MSSQL_SA_PASSWORD: this.mssqlPassword,
9096
});
9197

9298
return new StartedServiceBusContainer(await super.start(), mssql);
@@ -96,12 +102,12 @@ export class ServiceBusContainer extends GenericContainer {
96102
export class StartedServiceBusContainer extends AbstractStartedContainer {
97103
constructor(
98104
startedTestContainer: StartedTestContainer,
99-
private readonly mssql: StartedMSSQLServerContainer
105+
private readonly mssql: StartedTestContainer
100106
) {
101107
super(startedTestContainer);
102108
}
103109

104-
public getMssqlContainer(): StartedMSSQLServerContainer {
110+
public getMssqlContainer(): StartedTestContainer {
105111
return this.mssql;
106112
}
107113

packages/modules/azureservicebus/src/mssqlserver/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/modules/azureservicebus/src/mssqlserver/mssqlserver-container.ts

Lines changed: 0 additions & 81 deletions
This file was deleted.

0 commit comments

Comments
 (0)