chore(core): Check for instance type in offloading warning (#15960)

This commit is contained in:
Iván Ovejero
2025-06-05 11:19:55 +02:00
committed by GitHub
parent 2178cfe625
commit 5b3db5dddc
2 changed files with 86 additions and 53 deletions

View File

@@ -1,6 +1,8 @@
import type { Logger } from '@n8n/backend-common'; import type { Logger } from '@n8n/backend-common';
import { GlobalConfig } from '@n8n/config'; import { GlobalConfig } from '@n8n/config';
import { captor, mock } from 'jest-mock-extended'; import { captor, mock } from 'jest-mock-extended';
import { InstanceSettings } from 'n8n-core';
import type { InstanceType } from 'n8n-core';
import config from '@/config'; import config from '@/config';
import { mockInstance } from '@test/mocking'; import { mockInstance } from '@test/mocking';
@@ -10,7 +12,8 @@ import { DeprecationService } from '../deprecation.service';
describe('DeprecationService', () => { describe('DeprecationService', () => {
const logger = mock<Logger>(); const logger = mock<Logger>();
const globalConfig = mockInstance(GlobalConfig, { nodes: { exclude: [] } }); const globalConfig = mockInstance(GlobalConfig, { nodes: { exclude: [] } });
const deprecationService = new DeprecationService(logger, globalConfig); const instanceSettings = mockInstance(InstanceSettings, { instanceType: 'main' });
const deprecationService = new DeprecationService(logger, globalConfig, instanceSettings);
beforeEach(() => { beforeEach(() => {
// Ignore environment variables coming in from the environment when running // Ignore environment variables coming in from the environment when running
@@ -122,7 +125,7 @@ describe('DeprecationService', () => {
}, },
}); });
new DeprecationService(logger, globalConfig).warn(); new DeprecationService(logger, globalConfig, instanceSettings).warn();
expect(logger.warn).not.toHaveBeenCalled(); expect(logger.warn).not.toHaveBeenCalled();
}); });
@@ -140,33 +143,74 @@ describe('DeprecationService', () => {
}); });
}); });
describe('when executions.mode is queue', () => { describe('when executions.mode is not queue', () => {
test('should warn when OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS is false', () => { test.each([['main'], ['worker'], ['webhook']])(
'should not warn for instanceType %s',
(instanceType: InstanceType) => {
jest.spyOn(config, 'getEnv').mockImplementation((key) => {
if (key === 'executions.mode') return 'regular';
return;
});
process.env[envVar] = 'false'; process.env[envVar] = 'false';
const service = new DeprecationService(
const service = new DeprecationService(logger, globalConfig); logger,
globalConfig,
mock<InstanceSettings>({ instanceType }),
);
service.warn(); service.warn();
expect(logger.warn).not.toHaveBeenCalled();
expect(logger.warn).toHaveBeenCalledTimes(1); },
const warningMessage = logger.warn.mock.calls[0][0]; );
expect(warningMessage).toContain(envVar);
}); });
test('should warn when OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS is empty', () => { describe('when executions.mode is queue', () => {
process.env[envVar] = ''; describe('when instanceType is worker', () => {
test.each([
const service = new DeprecationService(logger, globalConfig); ['false', 'false'],
['empty string', ''],
])(`should not warn when ${envVar} is %s`, (_description, envValue) => {
process.env[envVar] = envValue;
const service = new DeprecationService(
logger,
globalConfig,
mock<InstanceSettings>({ instanceType: 'worker' }),
);
service.warn(); service.warn();
expect(logger.warn).not.toHaveBeenCalled();
});
});
expect(logger.warn).toHaveBeenCalledTimes(1); describe('when instanceType is webhook', () => {
const warningMessage = logger.warn.mock.calls[0][0]; test.each([
expect(warningMessage).toContain(envVar); ['false', 'false'],
['empty string', ''],
])(`should not warn when ${envVar} is %s`, (_description, envValue) => {
process.env[envVar] = envValue;
const service = new DeprecationService(
logger,
globalConfig,
mock<InstanceSettings>({ instanceType: 'webhook' }),
);
service.warn();
expect(logger.warn).not.toHaveBeenCalled();
});
});
describe('when instanceType is main', () => {
test.each([
['false', 'false'],
['empty string', ''],
])(`should warn when ${envVar} is %s`, (_description, envValue) => {
process.env[envVar] = envValue;
const service = new DeprecationService(logger, globalConfig, instanceSettings);
service.warn();
expect(logger.warn).toHaveBeenCalled();
}); });
test('should not warn when OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS is true', () => { test('should not warn when OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS is true', () => {
process.env[envVar] = 'true'; process.env[envVar] = 'true';
const service = new DeprecationService(logger, globalConfig); const service = new DeprecationService(logger, globalConfig, instanceSettings);
service.warn(); service.warn();
expect(logger.warn).not.toHaveBeenCalled(); expect(logger.warn).not.toHaveBeenCalled();
@@ -175,7 +219,7 @@ describe('DeprecationService', () => {
test('should warn when OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS is undefined', () => { test('should warn when OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS is undefined', () => {
delete process.env[envVar]; delete process.env[envVar];
const service = new DeprecationService(logger, globalConfig); const service = new DeprecationService(logger, globalConfig, instanceSettings);
service.warn(); service.warn();
expect(logger.warn).toHaveBeenCalledTimes(1); expect(logger.warn).toHaveBeenCalledTimes(1);
@@ -183,20 +227,6 @@ describe('DeprecationService', () => {
expect(warningMessage).toContain(envVar); expect(warningMessage).toContain(envVar);
}); });
}); });
describe('when executions.mode is not queue', () => {
test('should not warn', () => {
jest.spyOn(config, 'getEnv').mockImplementation((key) => {
if (key === 'executions.mode') return 'regular';
return;
});
process.env[envVar] = 'false';
const service = new DeprecationService(logger, globalConfig);
service.warn();
expect(logger.warn).not.toHaveBeenCalled();
});
}); });
}); });
}); });

View File

@@ -1,6 +1,7 @@
import { Logger } from '@n8n/backend-common'; import { Logger } from '@n8n/backend-common';
import { GlobalConfig } from '@n8n/config'; import { GlobalConfig } from '@n8n/config';
import { Service } from '@n8n/di'; import { Service } from '@n8n/di';
import { InstanceSettings } from 'n8n-core';
import config from '@/config'; import config from '@/config';
@@ -65,6 +66,7 @@ export class DeprecationService {
checkValue: (value?: string) => value?.toLowerCase() !== 'true' && value !== '1', checkValue: (value?: string) => value?.toLowerCase() !== 'true' && value !== '1',
warnIfMissing: true, warnIfMissing: true,
matchConfig: config.getEnv('executions.mode') === 'queue', matchConfig: config.getEnv('executions.mode') === 'queue',
disableIf: () => this.instanceSettings.instanceType !== 'main',
}, },
{ {
envVar: 'N8N_PARTIAL_EXECUTION_VERSION_DEFAULT', envVar: 'N8N_PARTIAL_EXECUTION_VERSION_DEFAULT',
@@ -103,6 +105,7 @@ export class DeprecationService {
constructor( constructor(
private readonly logger: Logger, private readonly logger: Logger,
private readonly globalConfig: GlobalConfig, private readonly globalConfig: GlobalConfig,
private readonly instanceSettings: InstanceSettings,
) {} ) {}
warn() { warn() {