testcontainers 9.3.0 → 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +17 -17
- package/dist/src/docker/docker-client.js +2 -45
- package/dist/src/docker/functions/container/exec-container.d.ts +1 -7
- package/dist/src/docker/functions/container/exec-container.js +4 -4
- package/dist/src/docker/resolve-host.d.ts +6 -0
- package/dist/src/docker/resolve-host.js +60 -0
- package/dist/src/docker/rootless-unix-socket-strategy.d.ts +2 -1
- package/dist/src/docker/rootless-unix-socket-strategy.js +10 -2
- package/dist/src/docker-compose/default-docker-compose-options.js +12 -0
- package/dist/src/docker-compose/functions/docker-compose-pull.d.ts +2 -0
- package/dist/src/docker-compose/functions/docker-compose-pull.js +35 -0
- package/dist/src/docker-compose/functions/docker-compose-up.js +2 -2
- package/dist/src/docker-compose-environment/docker-compose-environment.d.ts +4 -1
- package/dist/src/docker-compose-environment/docker-compose-environment.js +17 -5
- package/dist/src/dockerfile-parser.js +2 -1
- package/dist/src/generic-container/create-container-options.d.ts +3 -0
- package/dist/src/generic-container/create-container-options.js +18 -0
- package/dist/src/generic-container/generic-container.d.ts +17 -26
- package/dist/src/generic-container/generic-container.js +80 -83
- package/dist/src/generic-container/started-generic-container.d.ts +5 -3
- package/dist/src/generic-container/started-generic-container.js +13 -6
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.js +2 -2
- package/dist/src/modules/abstract-started-container.d.ts +2 -0
- package/dist/src/modules/abstract-started-container.js +10 -1
- package/dist/src/modules/arangodb/arangodb-container.js +1 -1
- package/dist/src/modules/elasticsearch/elasticsearch-container.js +7 -1
- package/dist/src/modules/kafka/kafka-container.d.ts +2 -3
- package/dist/src/modules/kafka/kafka-container.js +8 -8
- package/dist/src/modules/mongodb/mongodb-container.d.ts +1 -1
- package/dist/src/modules/mongodb/mongodb-container.js +2 -2
- package/dist/src/modules/mysql/mysql-container.js +1 -1
- package/dist/src/modules/nats/nats-container.js +4 -2
- package/dist/src/modules/neo4j/neo4j-container.js +1 -1
- package/dist/src/modules/postgresql/postgresql-container.js +2 -2
- package/dist/src/port-check.js +1 -1
- package/dist/src/reaper.js +1 -1
- package/dist/src/test-container.d.ts +1 -1
- package/dist/src/type-guards.d.ts +2 -0
- package/dist/src/type-guards.js +6 -4
- package/dist/src/wait-for-container.d.ts +1 -1
- package/dist/src/wait-strategy/default-wait-strategy.d.ts +3 -0
- package/dist/src/wait-strategy/default-wait-strategy.js +7 -0
- package/dist/src/wait-strategy/health-check-wait-strategy.d.ts +5 -0
- package/dist/src/wait-strategy/health-check-wait-strategy.js +31 -0
- package/dist/src/wait-strategy/host-port-wait-strategy.d.ts +13 -0
- package/dist/src/wait-strategy/host-port-wait-strategy.js +54 -0
- package/dist/src/{http-wait-strategy.d.ts → wait-strategy/http-wait-strategy.d.ts} +1 -1
- package/dist/src/{http-wait-strategy.js → wait-strategy/http-wait-strategy.js} +1 -1
- package/dist/src/wait-strategy/log-wait-strategy.d.ts +10 -0
- package/dist/src/wait-strategy/log-wait-strategy.js +67 -0
- package/dist/src/wait-strategy/shell-wait-strategy.d.ts +7 -0
- package/dist/src/wait-strategy/shell-wait-strategy.js +35 -0
- package/dist/src/{startup-check-strategy.js → wait-strategy/startup-check-strategy.js} +2 -2
- package/dist/src/wait-strategy/wait-strategy.d.ts +11 -0
- package/dist/src/wait-strategy/wait-strategy.js +13 -0
- package/dist/src/{wait.d.ts → wait-strategy/wait.d.ts} +4 -1
- package/dist/src/wait-strategy/wait.js +22 -0
- package/package.json +17 -17
- package/dist/src/wait-strategy.d.ts +0 -32
- package/dist/src/wait-strategy.js +0 -137
- package/dist/src/wait.js +0 -17
- /package/dist/src/{startup-check-strategy.d.ts → wait-strategy/startup-check-strategy.d.ts} +0 -0
|
@@ -20,7 +20,6 @@ const logger_1 = require("../logger");
|
|
|
20
20
|
const pull_policy_1 = require("../pull-policy");
|
|
21
21
|
const reaper_1 = require("../reaper");
|
|
22
22
|
const docker_image_name_1 = require("../docker-image-name");
|
|
23
|
-
const wait_strategy_1 = require("../wait-strategy");
|
|
24
23
|
const port_forwarder_1 = require("../port-forwarder");
|
|
25
24
|
const pull_image_1 = require("../docker/functions/image/pull-image");
|
|
26
25
|
const create_container_1 = require("../docker/functions/container/create-container");
|
|
@@ -36,6 +35,8 @@ const hash_1 = require("../hash");
|
|
|
36
35
|
const get_container_1 = require("../docker/functions/container/get-container");
|
|
37
36
|
const labels_1 = require("../labels");
|
|
38
37
|
const wait_for_container_1 = require("../wait-for-container");
|
|
38
|
+
const create_container_options_1 = require("./create-container-options");
|
|
39
|
+
const default_wait_strategy_1 = require("../wait-strategy/default-wait-strategy");
|
|
39
40
|
const reusableContainerCreationLock = new async_lock_1.default();
|
|
40
41
|
class GenericContainer {
|
|
41
42
|
static fromDockerfile(context, dockerfileName = "Dockerfile") {
|
|
@@ -43,66 +44,41 @@ class GenericContainer {
|
|
|
43
44
|
}
|
|
44
45
|
constructor(image) {
|
|
45
46
|
this.image = image;
|
|
46
|
-
this.environment = {};
|
|
47
|
-
this.networkAliases = [];
|
|
48
|
-
this.ports = [];
|
|
49
|
-
this.command = [];
|
|
50
|
-
this.bindMounts = [];
|
|
51
|
-
this.labels = {};
|
|
52
|
-
this.tmpFs = {};
|
|
53
47
|
this.startupTimeout = 60000;
|
|
54
|
-
this.
|
|
55
|
-
this.privilegedMode = false;
|
|
48
|
+
this.networkAliases = [];
|
|
56
49
|
this.pullPolicy = new pull_policy_1.DefaultPullPolicy();
|
|
57
|
-
|
|
58
|
-
this.
|
|
59
|
-
this.imageName = docker_image_name_1.DockerImageName.fromString(image);
|
|
50
|
+
const imageName = docker_image_name_1.DockerImageName.fromString(image);
|
|
51
|
+
this.opts = (0, create_container_options_1.initCreateContainerOptions)(imageName, imageName.isReaper());
|
|
60
52
|
}
|
|
61
53
|
start() {
|
|
62
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
63
55
|
const { dockerode, indexServerAddress } = yield (0, docker_client_1.dockerClient)();
|
|
64
56
|
yield (0, pull_image_1.pullImage)(dockerode, indexServerAddress, {
|
|
65
|
-
imageName: this.imageName,
|
|
57
|
+
imageName: this.opts.imageName,
|
|
66
58
|
force: this.pullPolicy.shouldPull(),
|
|
67
59
|
});
|
|
68
|
-
if (!this.
|
|
60
|
+
if (!this.opts.reusable && !this.opts.imageName.isReaper()) {
|
|
69
61
|
yield reaper_1.ReaperInstance.getInstance();
|
|
70
62
|
}
|
|
71
|
-
if (this.
|
|
63
|
+
if (this.beforeContainerStarted) {
|
|
64
|
+
yield this.beforeContainerStarted();
|
|
65
|
+
}
|
|
66
|
+
else if (this.preStart) {
|
|
72
67
|
yield this.preStart();
|
|
73
68
|
}
|
|
74
|
-
if (!this.imageName.isHelperContainer() && port_forwarder_1.PortForwarderInstance.isRunning()) {
|
|
69
|
+
if (!this.opts.imageName.isHelperContainer() && port_forwarder_1.PortForwarderInstance.isRunning()) {
|
|
75
70
|
const portForwarder = yield port_forwarder_1.PortForwarderInstance.getInstance();
|
|
76
|
-
this.extraHosts.push({ host: "host.testcontainers.internal", ipAddress: portForwarder.getIpAddress() });
|
|
71
|
+
this.opts.extraHosts.push({ host: "host.testcontainers.internal", ipAddress: portForwarder.getIpAddress() });
|
|
77
72
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
labels: this.labels,
|
|
88
|
-
reusable: this.reuse,
|
|
89
|
-
networkMode: this.networkAliases.length > 0 ? undefined : this.networkMode,
|
|
90
|
-
healthCheck: this.healthCheck,
|
|
91
|
-
useDefaultLogDriver: this.useDefaultLogDriver,
|
|
92
|
-
privilegedMode: this.privilegedMode,
|
|
93
|
-
autoRemove: this.imageName.isReaper(),
|
|
94
|
-
extraHosts: this.extraHosts,
|
|
95
|
-
ipcMode: this.ipcMode,
|
|
96
|
-
ulimits: this.ulimits,
|
|
97
|
-
addedCapabilities: this.addedCapabilities,
|
|
98
|
-
droppedCapabilities: this.droppedCapabilities,
|
|
99
|
-
user: this.user,
|
|
100
|
-
workingDir: this.workingDir,
|
|
101
|
-
resourcesQuota: this.resourcesQuota,
|
|
102
|
-
};
|
|
103
|
-
if (this.reuse) {
|
|
104
|
-
const containerHash = (0, hash_1.hash)(JSON.stringify(createContainerOptions));
|
|
105
|
-
createContainerOptions.labels = Object.assign(Object.assign({}, createContainerOptions.labels), { [labels_1.LABEL_TESTCONTAINERS_CONTAINER_HASH]: containerHash });
|
|
73
|
+
if (this.networkAliases.length > 0) {
|
|
74
|
+
this.opts.networkMode = undefined;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.opts.networkMode = this.networkMode;
|
|
78
|
+
}
|
|
79
|
+
if (this.opts.reusable) {
|
|
80
|
+
const containerHash = (0, hash_1.hash)(JSON.stringify(this.opts));
|
|
81
|
+
this.opts.labels = Object.assign(Object.assign({}, this.opts.labels), { [labels_1.LABEL_TESTCONTAINERS_CONTAINER_HASH]: containerHash });
|
|
106
82
|
logger_1.log.debug(`Container reuse has been enabled, hash: ${containerHash}`);
|
|
107
83
|
// We might have several async processes try to create a reusable container
|
|
108
84
|
// at once, to avoid possibly creating too many of these, use a lock
|
|
@@ -115,31 +91,41 @@ class GenericContainer {
|
|
|
115
91
|
}
|
|
116
92
|
else {
|
|
117
93
|
logger_1.log.debug("No container found to reuse");
|
|
118
|
-
return this.startContainer(
|
|
94
|
+
return this.startContainer(this.opts);
|
|
119
95
|
}
|
|
120
96
|
}));
|
|
121
97
|
}
|
|
122
98
|
else {
|
|
123
|
-
return this.startContainer(
|
|
99
|
+
return this.startContainer(this.opts);
|
|
124
100
|
}
|
|
125
101
|
});
|
|
126
102
|
}
|
|
127
|
-
reuseContainer(
|
|
103
|
+
reuseContainer(container) {
|
|
128
104
|
var _a;
|
|
129
105
|
return __awaiter(this, void 0, void 0, function* () {
|
|
130
106
|
const { host, hostIps } = yield (0, docker_client_1.dockerClient)();
|
|
131
|
-
const inspectResult = yield (0, inspect_container_1.inspectContainer)(
|
|
132
|
-
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, inspectResult).filter(this.
|
|
133
|
-
const waitStrategy = ((_a = this.waitStrategy) !== null && _a !== void 0 ? _a : (0,
|
|
134
|
-
|
|
135
|
-
|
|
107
|
+
const inspectResult = yield (0, inspect_container_1.inspectContainer)(container);
|
|
108
|
+
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, inspectResult).filter(this.opts.exposedPorts);
|
|
109
|
+
const waitStrategy = ((_a = this.waitStrategy) !== null && _a !== void 0 ? _a : (0, default_wait_strategy_1.defaultWaitStrategy)(host, container)).withStartupTimeout(this.startupTimeout);
|
|
110
|
+
if (this.containerStarting) {
|
|
111
|
+
yield this.containerStarting(inspectResult, true);
|
|
112
|
+
}
|
|
113
|
+
yield (0, wait_for_container_1.waitForContainer)(container, waitStrategy, host, boundPorts);
|
|
114
|
+
const startedContainer = new started_generic_container_1.StartedGenericContainer(container, host, inspectResult, boundPorts, inspectResult.name, waitStrategy);
|
|
115
|
+
if (this.containerStarted) {
|
|
116
|
+
yield this.containerStarted(startedContainer, inspectResult, true);
|
|
117
|
+
}
|
|
118
|
+
else if (this.postStart) {
|
|
119
|
+
yield this.postStart(startedContainer, inspectResult, boundPorts);
|
|
120
|
+
}
|
|
121
|
+
return startedContainer;
|
|
136
122
|
});
|
|
137
123
|
}
|
|
138
124
|
startContainer(createContainerOptions) {
|
|
139
125
|
var _a;
|
|
140
126
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
127
|
const container = yield (0, create_container_1.createContainer)(createContainerOptions);
|
|
142
|
-
if (!this.imageName.isHelperContainer() && port_forwarder_1.PortForwarderInstance.isRunning()) {
|
|
128
|
+
if (!this.opts.imageName.isHelperContainer() && port_forwarder_1.PortForwarderInstance.isRunning()) {
|
|
143
129
|
const portForwarder = yield port_forwarder_1.PortForwarderInstance.getInstance();
|
|
144
130
|
const portForwarderNetworkId = portForwarder.getNetworkId();
|
|
145
131
|
const excludedNetworks = [portForwarderNetworkId, "none", "host"];
|
|
@@ -162,62 +148,73 @@ class GenericContainer {
|
|
|
162
148
|
this.tarToCopy.finalize();
|
|
163
149
|
yield (0, put_container_archive_1.putContainerArchive)({ container, stream: this.tarToCopy, containerPath: "/" });
|
|
164
150
|
}
|
|
165
|
-
logger_1.log.info(`Starting container ${this.imageName} with ID: ${container.id}`);
|
|
151
|
+
logger_1.log.info(`Starting container ${this.opts.imageName} with ID: ${container.id}`);
|
|
152
|
+
if (this.containerCreated) {
|
|
153
|
+
yield this.containerCreated(container.id);
|
|
154
|
+
}
|
|
166
155
|
yield (0, start_container_1.startContainer)(container);
|
|
167
156
|
const { host, hostIps } = yield (0, docker_client_1.dockerClient)();
|
|
168
157
|
const inspectResult = yield (0, inspect_container_1.inspectContainer)(container);
|
|
169
|
-
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, inspectResult).filter(this.
|
|
170
|
-
const waitStrategy = ((_a = this.waitStrategy) !== null && _a !== void 0 ? _a : (0,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
158
|
+
const boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, inspectResult).filter(this.opts.exposedPorts);
|
|
159
|
+
const waitStrategy = ((_a = this.waitStrategy) !== null && _a !== void 0 ? _a : (0, default_wait_strategy_1.defaultWaitStrategy)(host, container)).withStartupTimeout(this.startupTimeout);
|
|
160
|
+
if (logger_1.containerLog.enabled()) {
|
|
161
|
+
(yield (0, container_logs_1.containerLogs)(container))
|
|
162
|
+
.on("data", (data) => logger_1.containerLog.trace(`${container.id}: ${data.trim()}`))
|
|
163
|
+
.on("err", (data) => logger_1.containerLog.error(`${container.id}: ${data.trim()}`));
|
|
164
|
+
}
|
|
165
|
+
if (this.containerStarting) {
|
|
166
|
+
yield this.containerStarting(inspectResult, false);
|
|
167
|
+
}
|
|
174
168
|
yield (0, wait_for_container_1.waitForContainer)(container, waitStrategy, host, boundPorts);
|
|
175
169
|
const startedContainer = new started_generic_container_1.StartedGenericContainer(container, host, inspectResult, boundPorts, inspectResult.name, waitStrategy);
|
|
176
|
-
if (this.
|
|
170
|
+
if (this.containerStarted) {
|
|
171
|
+
yield this.containerStarted(startedContainer, inspectResult, false);
|
|
172
|
+
}
|
|
173
|
+
else if (this.postStart) {
|
|
177
174
|
yield this.postStart(startedContainer, inspectResult, boundPorts);
|
|
178
175
|
}
|
|
179
176
|
return startedContainer;
|
|
180
177
|
});
|
|
181
178
|
}
|
|
182
179
|
get hasExposedPorts() {
|
|
183
|
-
return this.
|
|
180
|
+
return this.opts.exposedPorts.length !== 0;
|
|
184
181
|
}
|
|
185
182
|
withCommand(command) {
|
|
186
|
-
this.command = command;
|
|
183
|
+
this.opts.command = command;
|
|
187
184
|
return this;
|
|
188
185
|
}
|
|
189
186
|
withEntrypoint(entrypoint) {
|
|
190
|
-
this.entrypoint = entrypoint;
|
|
187
|
+
this.opts.entrypoint = entrypoint;
|
|
191
188
|
return this;
|
|
192
189
|
}
|
|
193
190
|
withName(name) {
|
|
194
|
-
this.name = name;
|
|
191
|
+
this.opts.name = name;
|
|
195
192
|
return this;
|
|
196
193
|
}
|
|
197
194
|
withLabels(labels) {
|
|
198
|
-
this.labels = Object.assign(Object.assign({}, this.labels), labels);
|
|
195
|
+
this.opts.labels = Object.assign(Object.assign({}, this.opts.labels), labels);
|
|
199
196
|
return this;
|
|
200
197
|
}
|
|
201
198
|
withEnvironment(environment) {
|
|
202
|
-
this.environment = Object.assign(Object.assign({}, this.environment), environment);
|
|
199
|
+
this.opts.environment = Object.assign(Object.assign({}, this.opts.environment), environment);
|
|
203
200
|
return this;
|
|
204
201
|
}
|
|
205
202
|
withTmpFs(tmpFs) {
|
|
206
|
-
this.tmpFs = Object.assign(Object.assign({}, this.tmpFs), tmpFs);
|
|
203
|
+
this.opts.tmpFs = Object.assign(Object.assign({}, this.opts.tmpFs), tmpFs);
|
|
207
204
|
return this;
|
|
208
205
|
}
|
|
209
206
|
withUlimits(ulimits) {
|
|
210
|
-
this.ulimits = Object.assign(Object.assign({}, this.ulimits), ulimits);
|
|
207
|
+
this.opts.ulimits = Object.assign(Object.assign({}, this.opts.ulimits), ulimits);
|
|
211
208
|
return this;
|
|
212
209
|
}
|
|
213
210
|
withAddedCapabilities(...capabilities) {
|
|
214
211
|
var _a;
|
|
215
|
-
this.addedCapabilities = [...((_a = this.addedCapabilities) !== null && _a !== void 0 ? _a : []), ...capabilities];
|
|
212
|
+
this.opts.addedCapabilities = [...((_a = this.opts.addedCapabilities) !== null && _a !== void 0 ? _a : []), ...capabilities];
|
|
216
213
|
return this;
|
|
217
214
|
}
|
|
218
215
|
withDroppedCapabilities(...capabilities) {
|
|
219
216
|
var _a;
|
|
220
|
-
this.droppedCapabilities = [...((_a = this.droppedCapabilities) !== null && _a !== void 0 ? _a : []), ...capabilities];
|
|
217
|
+
this.opts.droppedCapabilities = [...((_a = this.opts.droppedCapabilities) !== null && _a !== void 0 ? _a : []), ...capabilities];
|
|
221
218
|
return this;
|
|
222
219
|
}
|
|
223
220
|
withNetwork(network) {
|
|
@@ -233,19 +230,19 @@ class GenericContainer {
|
|
|
233
230
|
return this;
|
|
234
231
|
}
|
|
235
232
|
withExtraHosts(extraHosts) {
|
|
236
|
-
this.extraHosts = [...this.extraHosts, ...extraHosts];
|
|
233
|
+
this.opts.extraHosts = [...this.opts.extraHosts, ...extraHosts];
|
|
237
234
|
return this;
|
|
238
235
|
}
|
|
239
236
|
withExposedPorts(...ports) {
|
|
240
|
-
this.
|
|
237
|
+
this.opts.exposedPorts = [...this.opts.exposedPorts, ...ports];
|
|
241
238
|
return this;
|
|
242
239
|
}
|
|
243
240
|
withBindMounts(bindMounts) {
|
|
244
|
-
this.bindMounts = bindMounts.map((bindMount) => (Object.assign({ mode: "rw" }, bindMount)));
|
|
241
|
+
this.opts.bindMounts = bindMounts.map((bindMount) => (Object.assign({ mode: "rw" }, bindMount)));
|
|
245
242
|
return this;
|
|
246
243
|
}
|
|
247
244
|
withHealthCheck(healthCheck) {
|
|
248
|
-
this.healthCheck = healthCheck;
|
|
245
|
+
this.opts.healthCheck = healthCheck;
|
|
249
246
|
return this;
|
|
250
247
|
}
|
|
251
248
|
withStartupTimeout(startupTimeoutMs) {
|
|
@@ -257,19 +254,19 @@ class GenericContainer {
|
|
|
257
254
|
return this;
|
|
258
255
|
}
|
|
259
256
|
withDefaultLogDriver() {
|
|
260
|
-
this.useDefaultLogDriver = true;
|
|
257
|
+
this.opts.useDefaultLogDriver = true;
|
|
261
258
|
return this;
|
|
262
259
|
}
|
|
263
260
|
withPrivilegedMode() {
|
|
264
|
-
this.privilegedMode = true;
|
|
261
|
+
this.opts.privilegedMode = true;
|
|
265
262
|
return this;
|
|
266
263
|
}
|
|
267
264
|
withUser(user) {
|
|
268
|
-
this.user = user;
|
|
265
|
+
this.opts.user = user;
|
|
269
266
|
return this;
|
|
270
267
|
}
|
|
271
268
|
withReuse() {
|
|
272
|
-
this.
|
|
269
|
+
this.opts.reusable = true;
|
|
273
270
|
return this;
|
|
274
271
|
}
|
|
275
272
|
withPullPolicy(pullPolicy) {
|
|
@@ -277,7 +274,7 @@ class GenericContainer {
|
|
|
277
274
|
return this;
|
|
278
275
|
}
|
|
279
276
|
withIpcMode(ipcMode) {
|
|
280
|
-
this.ipcMode = ipcMode;
|
|
277
|
+
this.opts.ipcMode = ipcMode;
|
|
281
278
|
return this;
|
|
282
279
|
}
|
|
283
280
|
withCopyFilesToContainer(filesToCopy) {
|
|
@@ -297,7 +294,7 @@ class GenericContainer {
|
|
|
297
294
|
return this.tarToCopy;
|
|
298
295
|
}
|
|
299
296
|
withWorkingDir(workingDir) {
|
|
300
|
-
this.workingDir = workingDir;
|
|
297
|
+
this.opts.workingDir = workingDir;
|
|
301
298
|
return this;
|
|
302
299
|
}
|
|
303
300
|
withResourcesQuota({ memory, cpu }) {
|
|
@@ -305,7 +302,7 @@ class GenericContainer {
|
|
|
305
302
|
// see Memory, NanoCpus parameters
|
|
306
303
|
const ram = memory !== undefined ? memory * Math.pow(1024, 3) : undefined;
|
|
307
304
|
const cpuQuota = cpu !== undefined ? cpu * Math.pow(10, 9) : undefined;
|
|
308
|
-
this.resourcesQuota = { memory: ram, cpu: cpuQuota };
|
|
305
|
+
this.opts.resourcesQuota = { memory: ram, cpu: cpuQuota };
|
|
309
306
|
return this;
|
|
310
307
|
}
|
|
311
308
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import {
|
|
2
|
+
import { RestartOptions, StartedTestContainer, StopOptions, StoppedTestContainer } from "../test-container";
|
|
3
3
|
import Dockerode from "dockerode";
|
|
4
4
|
import { ExecResult, Labels } from "../docker/types";
|
|
5
5
|
import { InspectResult } from "../docker/functions/container/inspect-container";
|
|
6
6
|
import { BoundPorts } from "../bound-ports";
|
|
7
7
|
import { Readable } from "stream";
|
|
8
|
-
import { WaitStrategy } from "../wait-strategy";
|
|
8
|
+
import { WaitStrategy } from "../wait-strategy/wait-strategy";
|
|
9
9
|
export declare class StartedGenericContainer implements StartedTestContainer {
|
|
10
10
|
private readonly container;
|
|
11
11
|
private readonly host;
|
|
@@ -14,7 +14,9 @@ export declare class StartedGenericContainer implements StartedTestContainer {
|
|
|
14
14
|
private readonly name;
|
|
15
15
|
private readonly waitStrategy;
|
|
16
16
|
constructor(container: Dockerode.Container, host: string, inspectResult: InspectResult, boundPorts: BoundPorts, name: string, waitStrategy: WaitStrategy);
|
|
17
|
+
protected containerIsStopping?(): Promise<void>;
|
|
17
18
|
stop(options?: Partial<StopOptions>): Promise<StoppedTestContainer>;
|
|
19
|
+
protected containerIsStopped?(): Promise<void>;
|
|
18
20
|
restart(options?: Partial<RestartOptions>): Promise<void>;
|
|
19
21
|
private stopContainer;
|
|
20
22
|
getHost(): string;
|
|
@@ -26,6 +28,6 @@ export declare class StartedGenericContainer implements StartedTestContainer {
|
|
|
26
28
|
getNetworkNames(): string[];
|
|
27
29
|
getNetworkId(networkName: string): string;
|
|
28
30
|
getIpAddress(networkName: string): string;
|
|
29
|
-
exec(command: string[]
|
|
31
|
+
exec(command: string[]): Promise<ExecResult>;
|
|
30
32
|
logs(): Promise<Readable>;
|
|
31
33
|
}
|
|
@@ -43,9 +43,11 @@ class StartedGenericContainer {
|
|
|
43
43
|
const { hostIps } = yield (0, docker_client_1.dockerClient)();
|
|
44
44
|
this.inspectResult = yield (0, inspect_container_1.inspectContainer)(this.container);
|
|
45
45
|
const startTime = this.inspectResult.state.startedAt;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
if (logger_1.containerLog.enabled()) {
|
|
47
|
+
(yield (0, container_logs_1.containerLogs)(this.container, { since: startTime }))
|
|
48
|
+
.on("data", (data) => logger_1.containerLog.trace(`${this.container.id}: ${data.trim()}`))
|
|
49
|
+
.on("err", (data) => logger_1.containerLog.error(`${this.container.id}: ${data.trim()}`));
|
|
50
|
+
}
|
|
49
51
|
this.boundPorts = bound_ports_1.BoundPorts.fromInspectResult(hostIps, this.inspectResult).filter(Array.from(this.boundPorts.iterator()).map((port) => port[0]));
|
|
50
52
|
yield (0, wait_for_container_1.waitForContainer)(this.container, this.waitStrategy, this.host, this.boundPorts, startTime);
|
|
51
53
|
});
|
|
@@ -53,9 +55,15 @@ class StartedGenericContainer {
|
|
|
53
55
|
stopContainer(options = {}) {
|
|
54
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
57
|
logger_1.log.info(`Stopping container with ID: ${this.container.id}`);
|
|
58
|
+
if (this.containerIsStopping) {
|
|
59
|
+
yield this.containerIsStopping();
|
|
60
|
+
}
|
|
56
61
|
const resolvedOptions = Object.assign({ timeout: 0, removeVolumes: true }, options);
|
|
57
62
|
yield (0, stop_container_1.stopContainer)(this.container, { timeout: resolvedOptions.timeout });
|
|
58
63
|
yield (0, remove_container_1.removeContainer)(this.container, { removeVolumes: resolvedOptions.removeVolumes });
|
|
64
|
+
if (this.containerIsStopped) {
|
|
65
|
+
yield this.containerIsStopped();
|
|
66
|
+
}
|
|
59
67
|
return new stopped_generic_container_1.StoppedGenericContainer();
|
|
60
68
|
});
|
|
61
69
|
}
|
|
@@ -86,9 +94,8 @@ class StartedGenericContainer {
|
|
|
86
94
|
getIpAddress(networkName) {
|
|
87
95
|
return this.inspectResult.networkSettings[networkName].ipAddress;
|
|
88
96
|
}
|
|
89
|
-
exec(command
|
|
90
|
-
|
|
91
|
-
return (0, exec_container_1.execContainer)(this.container, command, resolvedOptions);
|
|
97
|
+
exec(command) {
|
|
98
|
+
return (0, exec_container_1.execContainer)(this.container, command);
|
|
92
99
|
}
|
|
93
100
|
logs() {
|
|
94
101
|
return (0, container_logs_1.containerLogs)(this.container);
|
package/dist/src/index.d.ts
CHANGED
|
@@ -7,9 +7,10 @@ export { StartedDockerComposeEnvironment } from "./docker-compose-environment/st
|
|
|
7
7
|
export { StoppedDockerComposeEnvironment } from "./docker-compose-environment/stopped-docker-compose-environment";
|
|
8
8
|
export { DownedDockerComposeEnvironment } from "./docker-compose-environment/downed-docker-compose-environment";
|
|
9
9
|
export { Network, StartedNetwork, StoppedNetwork } from "./network";
|
|
10
|
-
export { Wait } from "./wait";
|
|
11
|
-
export { StartupCheckStrategy, StartupStatus } from "./startup-check-strategy";
|
|
10
|
+
export { Wait } from "./wait-strategy/wait";
|
|
11
|
+
export { StartupCheckStrategy, StartupStatus } from "./wait-strategy/startup-check-strategy";
|
|
12
12
|
export { PullPolicy, DefaultPullPolicy, AlwaysPullPolicy } from "./pull-policy";
|
|
13
|
+
export { InspectResult } from "./docker/functions/container/inspect-container";
|
|
13
14
|
export { AbstractStartedContainer } from "./modules/abstract-started-container";
|
|
14
15
|
export { PostgreSqlContainer, StartedPostgreSqlContainer } from "./modules/postgresql/postgresql-container";
|
|
15
16
|
export { KafkaContainer, StartedKafkaContainer } from "./modules/kafka/kafka-container";
|
package/dist/src/index.js
CHANGED
|
@@ -19,9 +19,9 @@ var network_1 = require("./network");
|
|
|
19
19
|
Object.defineProperty(exports, "Network", { enumerable: true, get: function () { return network_1.Network; } });
|
|
20
20
|
Object.defineProperty(exports, "StartedNetwork", { enumerable: true, get: function () { return network_1.StartedNetwork; } });
|
|
21
21
|
Object.defineProperty(exports, "StoppedNetwork", { enumerable: true, get: function () { return network_1.StoppedNetwork; } });
|
|
22
|
-
var wait_1 = require("./wait");
|
|
22
|
+
var wait_1 = require("./wait-strategy/wait");
|
|
23
23
|
Object.defineProperty(exports, "Wait", { enumerable: true, get: function () { return wait_1.Wait; } });
|
|
24
|
-
var startup_check_strategy_1 = require("./startup-check-strategy");
|
|
24
|
+
var startup_check_strategy_1 = require("./wait-strategy/startup-check-strategy");
|
|
25
25
|
Object.defineProperty(exports, "StartupCheckStrategy", { enumerable: true, get: function () { return startup_check_strategy_1.StartupCheckStrategy; } });
|
|
26
26
|
var pull_policy_1 = require("./pull-policy");
|
|
27
27
|
Object.defineProperty(exports, "DefaultPullPolicy", { enumerable: true, get: function () { return pull_policy_1.DefaultPullPolicy; } });
|
|
@@ -5,7 +5,9 @@ import { Readable } from "stream";
|
|
|
5
5
|
export declare class AbstractStartedContainer implements StartedTestContainer {
|
|
6
6
|
protected readonly startedTestContainer: StartedTestContainer;
|
|
7
7
|
constructor(startedTestContainer: StartedTestContainer);
|
|
8
|
+
protected containerStopping?(): Promise<void>;
|
|
8
9
|
stop(options?: Partial<StopOptions>): Promise<StoppedTestContainer>;
|
|
10
|
+
protected containerStopped?(): Promise<void>;
|
|
9
11
|
restart(options?: Partial<RestartOptions>): Promise<void>;
|
|
10
12
|
getHost(): string;
|
|
11
13
|
getFirstMappedPort(): number;
|
|
@@ -15,7 +15,16 @@ class AbstractStartedContainer {
|
|
|
15
15
|
this.startedTestContainer = startedTestContainer;
|
|
16
16
|
}
|
|
17
17
|
stop(options) {
|
|
18
|
-
return this
|
|
18
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
19
|
+
if (this.containerStopping) {
|
|
20
|
+
yield this.containerStopping();
|
|
21
|
+
}
|
|
22
|
+
const stoppedContainer = this.startedTestContainer.stop(options);
|
|
23
|
+
if (this.containerStopped) {
|
|
24
|
+
yield this.containerStopped();
|
|
25
|
+
}
|
|
26
|
+
return stoppedContainer;
|
|
27
|
+
});
|
|
19
28
|
}
|
|
20
29
|
restart(options) {
|
|
21
30
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -28,7 +28,7 @@ class ArangoDBContainer extends __1.GenericContainer {
|
|
|
28
28
|
start: { get: () => super.start }
|
|
29
29
|
});
|
|
30
30
|
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
-
this.withExposedPorts(...(this.hasExposedPorts ? this.
|
|
31
|
+
this.withExposedPorts(...(this.hasExposedPorts ? this.opts.exposedPorts : [ARANGODB_PORT]))
|
|
32
32
|
.withWaitStrategy(__1.Wait.forLogMessage("Have fun!"))
|
|
33
33
|
.withEnvironment({ ARANGO_ROOT_PASSWORD: this.password })
|
|
34
34
|
.withStartupTimeout(120000);
|
|
@@ -22,8 +22,14 @@ class ElasticsearchContainer extends __1.GenericContainer {
|
|
|
22
22
|
start: { get: () => super.start }
|
|
23
23
|
});
|
|
24
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
this.withExposedPorts(...(this.hasExposedPorts ? this.
|
|
25
|
+
this.withExposedPorts(...(this.hasExposedPorts ? this.opts.exposedPorts : [ELASTIC_SEARCH_HTTP_PORT]))
|
|
26
26
|
.withEnvironment({ "discovery.type": "single-node" })
|
|
27
|
+
.withCopyContentToContainer([
|
|
28
|
+
{
|
|
29
|
+
content: "-Xms2G\n-Xmx2G\n",
|
|
30
|
+
target: "/usr/share/elasticsearch/config/jvm.options.d/elasticsearch-default-memory-vm.options",
|
|
31
|
+
},
|
|
32
|
+
])
|
|
27
33
|
.withStartupTimeout(120000);
|
|
28
34
|
return new StartedElasticsearchContainer(yield _super.start.call(this));
|
|
29
35
|
});
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { GenericContainer } from "../../generic-container/generic-container";
|
|
2
|
-
import { BoundPorts } from "../../bound-ports";
|
|
3
2
|
import { StartedTestContainer } from "../..";
|
|
4
3
|
import { AbstractStartedContainer } from "../abstract-started-container";
|
|
5
4
|
import { InspectResult } from "../../docker/functions/container/inspect-container";
|
|
@@ -32,9 +31,9 @@ export declare class KafkaContainer extends GenericContainer {
|
|
|
32
31
|
constructor(image?: string);
|
|
33
32
|
withZooKeeper(host: string, port: number): this;
|
|
34
33
|
withSaslSslListener(options: SaslSslListenerOptions): this;
|
|
35
|
-
protected
|
|
34
|
+
protected beforeContainerStarted(): Promise<void>;
|
|
36
35
|
start(): Promise<StartedKafkaContainer>;
|
|
37
|
-
protected
|
|
36
|
+
protected containerStarted(container: StartedTestContainer, inspectResult: InspectResult): Promise<void>;
|
|
38
37
|
private addPlaintextAndSecureListener;
|
|
39
38
|
private addPlaintextListener;
|
|
40
39
|
private updateAdvertisedListeners;
|
|
@@ -44,7 +44,7 @@ class KafkaContainer extends generic_container_1.GenericContainer {
|
|
|
44
44
|
this.saslSslConfig = options;
|
|
45
45
|
return this;
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
beforeContainerStarted() {
|
|
48
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
49
|
const network = this.networkMode && this.networkAliases.length > 0 ? this.networkAliases[0] : "localhost";
|
|
50
50
|
this.withEnvironment({ KAFKA_ADVERTISED_LISTENERS: `BROKER://${network}:${KAFKA_BROKER_PORT}` });
|
|
@@ -81,9 +81,9 @@ class KafkaContainer extends generic_container_1.GenericContainer {
|
|
|
81
81
|
return new StartedKafkaContainer(yield _super.start.call(this));
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
containerStarted(container, inspectResult) {
|
|
85
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
-
yield this.updateAdvertisedListeners(container, inspectResult
|
|
86
|
+
yield this.updateAdvertisedListeners(container, inspectResult);
|
|
87
87
|
if (this.saslSslConfig) {
|
|
88
88
|
yield this.createUser(container, this.saslSslConfig.sasl);
|
|
89
89
|
}
|
|
@@ -117,12 +117,12 @@ class KafkaContainer extends generic_container_1.GenericContainer {
|
|
|
117
117
|
KAFKA_LISTENERS: `PLAINTEXT://0.0.0.0:${KAFKA_PORT},BROKER://0.0.0.0:${KAFKA_BROKER_PORT}`,
|
|
118
118
|
}).withExposedPorts(KAFKA_PORT);
|
|
119
119
|
}
|
|
120
|
-
updateAdvertisedListeners(container, inspectResult
|
|
120
|
+
updateAdvertisedListeners(container, inspectResult) {
|
|
121
121
|
return __awaiter(this, void 0, void 0, function* () {
|
|
122
122
|
const brokerAdvertisedListener = `BROKER://${inspectResult.hostname}:${KAFKA_BROKER_PORT}`;
|
|
123
|
-
let bootstrapServers = `PLAINTEXT://${container.getHost()}:${
|
|
123
|
+
let bootstrapServers = `PLAINTEXT://${container.getHost()}:${container.getMappedPort(KAFKA_PORT)}`;
|
|
124
124
|
if (this.saslSslConfig) {
|
|
125
|
-
bootstrapServers = `${bootstrapServers},SECURE://${container.getHost()}:${
|
|
125
|
+
bootstrapServers = `${bootstrapServers},SECURE://${container.getHost()}:${container.getMappedPort(this.saslSslConfig.port)}`;
|
|
126
126
|
}
|
|
127
127
|
const { output, exitCode } = yield container.exec([
|
|
128
128
|
"kafka-configs",
|
|
@@ -132,7 +132,7 @@ class KafkaContainer extends generic_container_1.GenericContainer {
|
|
|
132
132
|
"--entity-type",
|
|
133
133
|
"brokers",
|
|
134
134
|
"--entity-name",
|
|
135
|
-
this.environment["KAFKA_BROKER_ID"],
|
|
135
|
+
this.opts.environment["KAFKA_BROKER_ID"],
|
|
136
136
|
"--add-config",
|
|
137
137
|
`advertised.listeners=[${bootstrapServers},${brokerAdvertisedListener}]`,
|
|
138
138
|
]);
|
|
@@ -149,7 +149,7 @@ class KafkaContainer extends generic_container_1.GenericContainer {
|
|
|
149
149
|
// At the time of writing kafka-configs displays a warning stating that the 'zookeeper' flag is deprecated in favor of 'bootstrap-server'.
|
|
150
150
|
// Unfortunately, 'bootstrap-server' can only be used to set quotas and not to create a user.
|
|
151
151
|
"--zookeeper",
|
|
152
|
-
this.environment["KAFKA_ZOOKEEPER_CONNECT"],
|
|
152
|
+
this.opts.environment["KAFKA_ZOOKEEPER_CONNECT"],
|
|
153
153
|
"--entity-type",
|
|
154
154
|
"users",
|
|
155
155
|
"--entity-name",
|
|
@@ -5,7 +5,7 @@ export declare class MongoDBContainer extends GenericContainer {
|
|
|
5
5
|
private readonly dockerImageName;
|
|
6
6
|
constructor(image?: string);
|
|
7
7
|
start(): Promise<StartedMongoDBContainer>;
|
|
8
|
-
protected
|
|
8
|
+
protected containerStarted(startedTestContainer: StartedTestContainer): Promise<void>;
|
|
9
9
|
private initReplicaSet;
|
|
10
10
|
private executeMongoEvalCommand;
|
|
11
11
|
private buildMongoEvalCommand;
|
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.StartedMongoDBContainer = exports.MongoDBContainer = void 0;
|
|
13
13
|
const generic_container_1 = require("../../generic-container/generic-container");
|
|
14
14
|
const abstract_started_container_1 = require("../abstract-started-container");
|
|
15
|
-
const wait_1 = require("../../wait");
|
|
15
|
+
const wait_1 = require("../../wait-strategy/wait");
|
|
16
16
|
const docker_image_name_1 = require("../../docker-image-name");
|
|
17
17
|
const MONGODB_PORT = 27017;
|
|
18
18
|
class MongoDBContainer extends generic_container_1.GenericContainer {
|
|
@@ -32,7 +32,7 @@ class MongoDBContainer extends generic_container_1.GenericContainer {
|
|
|
32
32
|
return new StartedMongoDBContainer(yield _super.start.call(this));
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
containerStarted(startedTestContainer) {
|
|
36
36
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
37
|
yield this.initReplicaSet(startedTestContainer);
|
|
38
38
|
});
|
|
@@ -42,7 +42,7 @@ class MySqlContainer extends generic_container_1.GenericContainer {
|
|
|
42
42
|
start: { get: () => super.start }
|
|
43
43
|
});
|
|
44
44
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
this.withExposedPorts(...(this.hasExposedPorts ? this.
|
|
45
|
+
this.withExposedPorts(...(this.hasExposedPorts ? this.opts.exposedPorts : [MYSQL_PORT]))
|
|
46
46
|
.withEnvironment({
|
|
47
47
|
MYSQL_DATABASE: this.database,
|
|
48
48
|
MYSQL_ROOT_PASSWORD: this.rootPassword,
|
|
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.StartedNatsContainer = exports.NatsContainer = void 0;
|
|
13
13
|
const generic_container_1 = require("../../generic-container/generic-container");
|
|
14
14
|
const abstract_started_container_1 = require("../abstract-started-container");
|
|
15
|
-
const wait_1 = require("../../wait");
|
|
15
|
+
const wait_1 = require("../../wait-strategy/wait");
|
|
16
16
|
const CLIENT_PORT = 4222;
|
|
17
17
|
const ROUTING_PORT_FOR_CLUSTERING = 6222;
|
|
18
18
|
const HTTP_MANAGEMENT_PORT = 8222;
|
|
@@ -64,7 +64,9 @@ class NatsContainer extends generic_container_1.GenericContainer {
|
|
|
64
64
|
return result;
|
|
65
65
|
}
|
|
66
66
|
this.withCommand(buildCmdsFromArgs(this.args))
|
|
67
|
-
.withExposedPorts(...(this.hasExposedPorts
|
|
67
|
+
.withExposedPorts(...(this.hasExposedPorts
|
|
68
|
+
? this.opts.exposedPorts
|
|
69
|
+
: [CLIENT_PORT, ROUTING_PORT_FOR_CLUSTERING, HTTP_MANAGEMENT_PORT]))
|
|
68
70
|
.withWaitStrategy(wait_1.Wait.forLogMessage(/.*Server is ready.*/))
|
|
69
71
|
.withStartupTimeout(120000);
|
|
70
72
|
return new StartedNatsContainer(yield _super.start.call(this), this.getUser(), this.getPass());
|
|
@@ -38,7 +38,7 @@ class Neo4jContainer extends __1.GenericContainer {
|
|
|
38
38
|
start: { get: () => super.start }
|
|
39
39
|
});
|
|
40
40
|
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
-
this.withExposedPorts(...(this.hasExposedPorts ? this.
|
|
41
|
+
this.withExposedPorts(...(this.hasExposedPorts ? this.opts.exposedPorts : [BOLT_PORT, HTTP_PORT]))
|
|
42
42
|
.withWaitStrategy(__1.Wait.forLogMessage("Started."))
|
|
43
43
|
.withEnvironment({ NEO4J_AUTH: `${USERNAME}/${this.password}` })
|
|
44
44
|
.withStartupTimeout(120000);
|