dockest
Version:
Dockest is an integration testing tool aimed at alleviating the process of evaluating unit tests whilst running multi-container Docker applications.
80 lines • 3.63 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkConnection = exports.createCheckConnection = void 0;
const net_1 = __importDefault(require("net"));
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const errors_1 = require("../../errors");
const select_port_mapping_1 = require("../../utils/select-port-mapping");
const LOG_PREFIX = '[Check Connection]';
const RETRY_COUNT = 10;
const acquireConnection = ({ host, port }) => {
return new Promise((resolve, reject) => {
let connected = false;
let timeoutId = null;
const netSocket = net_1.default.createConnection({ host, port }).on('connect', () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
console.debug(`${host}:${port} connected ✅`);
connected = true;
netSocket.end();
resolve(undefined);
});
timeoutId = setTimeout(() => {
if (!connected) {
reject(new Error('Timeout while acquiring connection'));
}
}, 1000);
});
};
const checkPortConnection = ({ host, port, runner, acquireConnection, }) => {
return (0, rxjs_1.of)({ host, port }).pipe(
// run check
(0, operators_1.mergeMap)(({ host, port }) => {
return (0, rxjs_1.from)(acquireConnection({ host, port }));
}),
// retry if check errors
(0, operators_1.retryWhen)((errors) => {
let retries = 0;
return errors.pipe((0, operators_1.tap)((value) => {
retries = retries + 1;
runner.logger.error(`${LOG_PREFIX} Error: ${value.message}`);
runner.logger.debug(`${LOG_PREFIX} Timeout after ${RETRY_COUNT - retries} retries (Retry count set to ${RETRY_COUNT}).
`);
}), (0, operators_1.takeWhile)(() => {
if (retries < RETRY_COUNT) {
return true;
}
throw new errors_1.DockestError(`${LOG_PREFIX} Timed out`, { runner });
}), (0, operators_1.delay)(1000));
}));
};
const createCheckConnection = ({ acquireConnection }) => async ({ runner, runner: { dockerComposeFileService: { ports }, host: runnerHost, isBridgeNetworkMode, dockerEventStream$, }, }) => {
const host = runnerHost || 'localhost';
const portKey = isBridgeNetworkMode ? 'target' : 'published';
if (!ports || ports.length === 0) {
runner.logger.debug(`${LOG_PREFIX} Skip connection check as there are no ports exposed.`);
return;
}
return (0, rxjs_1.race)(dockerEventStream$.pipe((0, operators_1.skipWhile)((event) => event.action !== 'die' && event.action !== 'kill'), (0, operators_1.map)((event) => {
throw new errors_1.DockestError('Container unexpectedly died.', { event });
})), (0, rxjs_1.of)(...ports.map(select_port_mapping_1.selectPortMapping)).pipe(
// concatMap -> run checks for each port in sequence
(0, operators_1.concatMap)(({ [portKey]: port }) => {
return checkPortConnection({
runner,
host,
port,
acquireConnection,
});
}),
// we do not care about the single elements, we only want this stream to complete without errors.
(0, operators_1.ignoreElements)())).toPromise();
};
exports.createCheckConnection = createCheckConnection;
exports.checkConnection = (0, exports.createCheckConnection)({ acquireConnection });
//# sourceMappingURL=check-connection.js.map