mirror of
https://github.com/n8n-io/n8n
synced 2026-04-21 07:37:20 +00:00
fix(core): Force full execution data fetching for evaluation test runs (#27335)
This commit is contained in:
parent
3ad5926a5e
commit
87afcd8db4
6 changed files with 87 additions and 2 deletions
15
.vscode/launch.json
vendored
15
.vscode/launch.json
vendored
|
|
@ -32,6 +32,21 @@
|
|||
"outputCapture": "std",
|
||||
"killBehavior": "forceful"
|
||||
},
|
||||
{
|
||||
"name": "Launch n8n CLI worker dev with debug",
|
||||
"runtimeExecutable": "pnpm",
|
||||
"cwd": "${workspaceFolder}/packages/cli",
|
||||
"runtimeArgs": ["run", "dev:worker", "--", "--inspect-brk"],
|
||||
"console": "integratedTerminal",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true,
|
||||
"request": "launch",
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"type": "node",
|
||||
"envFile": "${workspaceFolder}/.env",
|
||||
"outputCapture": "std",
|
||||
"killBehavior": "polite"
|
||||
},
|
||||
{
|
||||
"name": "Launch n8n CLI dev with debug",
|
||||
"runtimeExecutable": "pnpm",
|
||||
|
|
|
|||
|
|
@ -572,6 +572,57 @@ describe('workflow timeout with startedAt', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('needsFullExecutionData', () => {
|
||||
const originalEnv = process.env.N8N_MINIMIZE_EXECUTION_DATA_FETCHING;
|
||||
|
||||
afterEach(() => {
|
||||
if (originalEnv === undefined) {
|
||||
delete process.env.N8N_MINIMIZE_EXECUTION_DATA_FETCHING;
|
||||
} else {
|
||||
process.env.N8N_MINIMIZE_EXECUTION_DATA_FETCHING = originalEnv;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return true when forceFullExecutionData is true even with N8N_MINIMIZE_EXECUTION_DATA_FETCHING set', () => {
|
||||
process.env.N8N_MINIMIZE_EXECUTION_DATA_FETCHING = 'true';
|
||||
|
||||
// @ts-expect-error Private method
|
||||
const result = runner.needsFullExecutionData('evaluation', 'exec-id', true);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when env var is not set and forceFullExecutionData is undefined', () => {
|
||||
delete process.env.N8N_MINIMIZE_EXECUTION_DATA_FETCHING;
|
||||
|
||||
// @ts-expect-error Private method
|
||||
const result = runner.needsFullExecutionData('webhook', 'exec-id', undefined);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when env var is set, forceFullExecutionData is undefined, and mode is not integrated', () => {
|
||||
process.env.N8N_MINIMIZE_EXECUTION_DATA_FETCHING = 'true';
|
||||
|
||||
const activeExecutions = Container.get(ActiveExecutions);
|
||||
jest.spyOn(activeExecutions, 'getResponseMode').mockReturnValue('responseNode');
|
||||
|
||||
// @ts-expect-error Private method
|
||||
const result = runner.needsFullExecutionData('webhook', 'exec-id', undefined);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true when env var is set and mode is integrated', () => {
|
||||
process.env.N8N_MINIMIZE_EXECUTION_DATA_FETCHING = 'true';
|
||||
|
||||
// @ts-expect-error Private method
|
||||
const result = runner.needsFullExecutionData('integrated', 'exec-id', undefined);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('streaming functionality', () => {
|
||||
it('should setup sendChunk handler when streaming is enabled and execution mode is not manual', async () => {
|
||||
// ARRANGE
|
||||
|
|
|
|||
|
|
@ -489,6 +489,7 @@ describe('TestRunnerService', () => {
|
|||
resource: 'dataset',
|
||||
operation: 'getRows',
|
||||
});
|
||||
expect(runCallArg).toHaveProperty('forceFullExecutionData', true);
|
||||
});
|
||||
|
||||
test('should call workflowRunner.run with correct data in queue execution mode and manual offload', async () => {
|
||||
|
|
@ -575,6 +576,7 @@ describe('TestRunnerService', () => {
|
|||
resource: 'dataset',
|
||||
operation: 'getRows',
|
||||
});
|
||||
expect(runCallArg).toHaveProperty('forceFullExecutionData', true);
|
||||
|
||||
// after reset
|
||||
delete process.env.OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS;
|
||||
|
|
@ -742,6 +744,7 @@ describe('TestRunnerService', () => {
|
|||
},
|
||||
},
|
||||
userId: metadata.userId,
|
||||
forceFullExecutionData: true,
|
||||
triggerToStartFrom: {
|
||||
name: triggerNodeName,
|
||||
},
|
||||
|
|
@ -869,6 +872,7 @@ describe('TestRunnerService', () => {
|
|||
expect(runCallArg).toEqual(
|
||||
expect.objectContaining({
|
||||
executionMode: 'evaluation',
|
||||
forceFullExecutionData: true,
|
||||
pinData: {
|
||||
[triggerNodeName]: [testCase],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ export class TestRunnerService {
|
|||
const data: IWorkflowExecutionDataProcess = {
|
||||
executionMode: 'evaluation',
|
||||
pinData,
|
||||
forceFullExecutionData: true,
|
||||
workflowData: {
|
||||
...workflow,
|
||||
settings: {
|
||||
|
|
@ -336,6 +337,7 @@ export class TestRunnerService {
|
|||
destinationNode: { nodeName: triggerNode.name, mode: 'inclusive' },
|
||||
executionMode: 'manual',
|
||||
runData: {},
|
||||
forceFullExecutionData: true,
|
||||
workflowData: {
|
||||
...workflow,
|
||||
settings: {
|
||||
|
|
|
|||
|
|
@ -489,7 +489,10 @@ export class WorkflowRunner {
|
|||
|
||||
let runData: IRun;
|
||||
|
||||
if (!jobResult || this.needsFullExecutionData(data.executionMode, executionId)) {
|
||||
if (
|
||||
!jobResult ||
|
||||
this.needsFullExecutionData(data.executionMode, executionId, data.forceFullExecutionData)
|
||||
) {
|
||||
const fullExecutionData = await this.executionRepository.findSingleExecution(
|
||||
executionId,
|
||||
{
|
||||
|
|
@ -561,7 +564,12 @@ export class WorkflowRunner {
|
|||
* In all other cases we can skip the DB fetch and use the lightweight
|
||||
* result summary sent by the worker via the job progress message.
|
||||
*/
|
||||
private needsFullExecutionData(executionMode: WorkflowExecuteMode, executionId: string): boolean {
|
||||
private needsFullExecutionData(
|
||||
executionMode: WorkflowExecuteMode,
|
||||
executionId: string,
|
||||
forceFullExecutionData?: boolean,
|
||||
): boolean {
|
||||
if (forceFullExecutionData) return true;
|
||||
if (!process.env.N8N_MINIMIZE_EXECUTION_DATA_FETCHING) return true;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -2880,6 +2880,11 @@ export interface IWorkflowExecutionDataProcess {
|
|||
destinationNode?: IDestinationNode;
|
||||
restartExecutionId?: string;
|
||||
executionMode: WorkflowExecuteMode;
|
||||
/**
|
||||
* When true, forces the execution data to be present in the run data
|
||||
* ignores N8N_MINIMIZE_EXECUTION_DATA_FETCHING environment variable if set
|
||||
*/
|
||||
forceFullExecutionData?: boolean;
|
||||
/**
|
||||
* The data that is sent in the body of the webhook that started this
|
||||
* execution.
|
||||
|
|
|
|||
Loading…
Reference in a new issue