mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-11 22:50:06 +00:00
fix: Wait for MockServer HTTP status without following logs (#40846)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
n8n-cat-bot[bot]
parent
3301b2cc0f
commit
45938389b8
@@ -11,20 +11,17 @@ import type {
|
||||
import { join } from 'path';
|
||||
import { GenericContainer, Wait } from 'testcontainers';
|
||||
|
||||
import { createSilentLogConsumer } from '../helpers/utils';
|
||||
import { TEST_CONTAINER_IMAGES } from '../test-containers';
|
||||
import type { HelperContext, Service, ServiceResult } from './types';
|
||||
|
||||
const HOSTNAME = 'proxyserver';
|
||||
const PORT = 1080;
|
||||
const MOCKSERVER_WAIT_STRATEGY = Wait.forAll([
|
||||
Wait.forLogMessage(`INFO ${PORT} started on port: ${PORT}`),
|
||||
Wait.forHttp('/mockserver/status', PORT)
|
||||
.withMethod('PUT')
|
||||
.forStatusCode(200)
|
||||
.withStartupTimeout(60_000)
|
||||
.withReadTimeout(250),
|
||||
]);
|
||||
// The status check proves readiness without following MockServer logs.
|
||||
const MOCKSERVER_WAIT_STRATEGY = Wait.forHttp('/mockserver/status', PORT)
|
||||
.withMethod('PUT')
|
||||
.forStatusCode(200)
|
||||
.withStartupTimeout(60_000)
|
||||
.withReadTimeout(250);
|
||||
|
||||
export interface ProxyMeta {
|
||||
host: string;
|
||||
@@ -49,36 +46,29 @@ export const proxy: Service<ProxyResult> = {
|
||||
},
|
||||
|
||||
async start(network, projectName): Promise<ProxyResult> {
|
||||
const { consumer, throwWithLogs } = createSilentLogConsumer();
|
||||
const container = await new GenericContainer(TEST_CONTAINER_IMAGES.mockserver)
|
||||
.withNetwork(network)
|
||||
.withNetworkAliases(HOSTNAME)
|
||||
.withExposedPorts(PORT)
|
||||
// Keep MockServer heap predictable under parallel container load.
|
||||
.withEnvironment({ JVM_OPTIONS: '-Xmx512m -Xms512m' })
|
||||
.withWaitStrategy(MOCKSERVER_WAIT_STRATEGY)
|
||||
.withLabels({
|
||||
'com.docker.compose.project': projectName,
|
||||
'com.docker.compose.service': HOSTNAME,
|
||||
})
|
||||
.withName(`${projectName}-${HOSTNAME}`)
|
||||
.withReuse()
|
||||
.start();
|
||||
|
||||
try {
|
||||
const container = await new GenericContainer(TEST_CONTAINER_IMAGES.mockserver)
|
||||
.withNetwork(network)
|
||||
.withNetworkAliases(HOSTNAME)
|
||||
.withExposedPorts(PORT)
|
||||
// Keep MockServer heap predictable under parallel container load.
|
||||
.withEnvironment({ JVM_OPTIONS: '-Xmx512m -Xms512m' })
|
||||
.withWaitStrategy(MOCKSERVER_WAIT_STRATEGY)
|
||||
.withLabels({
|
||||
'com.docker.compose.project': projectName,
|
||||
'com.docker.compose.service': HOSTNAME,
|
||||
})
|
||||
.withName(`${projectName}-${HOSTNAME}`)
|
||||
.withReuse()
|
||||
.withLogConsumer(consumer)
|
||||
.start();
|
||||
|
||||
return {
|
||||
container,
|
||||
meta: {
|
||||
host: HOSTNAME,
|
||||
port: PORT,
|
||||
internalUrl: `http://${HOSTNAME}:${PORT}`,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
return throwWithLogs(error);
|
||||
}
|
||||
return {
|
||||
container,
|
||||
meta: {
|
||||
host: HOSTNAME,
|
||||
port: PORT,
|
||||
internalUrl: `http://${HOSTNAME}:${PORT}`,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
env(result: ProxyResult, external?: boolean): Record<string, string> {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import {
|
||||
GenericContainer,
|
||||
Wait,
|
||||
type StartedNetwork,
|
||||
type StartedTestContainer,
|
||||
} from 'testcontainers';
|
||||
import { afterEach, expect, test, vi } from 'vitest';
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
test('waits for MockServer status without a followed log stream', async () => {
|
||||
const httpWait = vi.spyOn(Wait, 'forHttp');
|
||||
const logWait = vi.spyOn(Wait, 'forLogMessage');
|
||||
const withWaitStrategy = vi.spyOn(GenericContainer.prototype, 'withWaitStrategy');
|
||||
const withLogConsumer = vi.spyOn(GenericContainer.prototype, 'withLogConsumer');
|
||||
vi.spyOn(GenericContainer.prototype, 'start').mockResolvedValue({} as StartedTestContainer);
|
||||
const { proxy } = await import('../services/proxy.js');
|
||||
const network = { getName: () => 'test-network' } as StartedNetwork;
|
||||
|
||||
const result = await proxy.start(network, 'test-project');
|
||||
|
||||
expect(result.meta.internalUrl).toBe('http://proxyserver:1080');
|
||||
expect(httpWait).toHaveBeenCalledWith('/mockserver/status', 1080);
|
||||
// DEVP-1269: Log waits and consumers leave followed Docker streams attached to the worker.
|
||||
expect(logWait).not.toHaveBeenCalled();
|
||||
expect(withWaitStrategy).toHaveBeenCalledWith(httpWait.mock.results[0].value);
|
||||
expect(withLogConsumer).not.toHaveBeenCalled();
|
||||
});
|
||||
Reference in New Issue
Block a user