more tests

This commit is contained in:
Eric Allam
2025-03-25 11:18:27 +00:00
parent 5edbb77dfe
commit 6ba2b0476b
4 changed files with 272 additions and 17 deletions
+2 -2
View File
@@ -13,12 +13,12 @@ But often, when running tests, it's better to `cd` into the directory and then r
```
cd apps/webapp
pnpm run test
pnpm run test --run
```
This way you can run for a single file easily:
```
cd internal-packages/run-engine
pnpm run test ./src/engine/tests/ttl.test.ts
pnpm run test ./src/engine/tests/ttl.test.ts --run
```
@@ -358,7 +358,7 @@ const zodIpc = new ZodIpcConnection({
tracer,
tracingSDK,
consoleInterceptor,
config,
retries: config.retries,
handleErrorFn,
});
@@ -406,13 +406,7 @@ const zodIpc = new ZodIpcConnection({
}
});
const { result } = await executor.execute(
execution,
metadata,
traceContext,
measurement,
signal
);
const { result } = await executor.execute(execution, metadata, traceContext, signal);
const usageSample = usage.stop(measurement);
+18 -7
View File
@@ -377,7 +377,11 @@ export class TaskExecutor {
)
);
if (!hookError && result && typeof result === "object" && !Array.isArray(result)) {
if (hookError) {
throw hookError;
}
if (result && typeof result === "object" && !Array.isArray(result)) {
globalResults.push(result);
}
}
@@ -407,13 +411,12 @@ export class TaskExecutor {
)
);
if (hookError) {
throw hookError;
}
// Only merge if taskResult is an object
if (
!hookError &&
taskResult &&
typeof taskResult === "object" &&
!Array.isArray(taskResult)
) {
if (taskResult && typeof taskResult === "object" && !Array.isArray(taskResult)) {
return { ...mergedGlobalResults, ...taskResult };
}
@@ -645,6 +648,10 @@ export class TaskExecutor {
}
)
);
if (hookError) {
throw hookError;
}
}
if (taskStartHook) {
@@ -667,6 +674,10 @@ export class TaskExecutor {
}
)
);
if (hookError) {
throw hookError;
}
}
}
);
+250
View File
@@ -953,6 +953,256 @@ describe("TaskExecutor", () => {
},
});
});
test("should propagate errors from init hooks", async () => {
const executionOrder: string[] = [];
const expectedError = new Error("Init hook error");
// Register global init hook that throws an error
lifecycleHooks.registerGlobalInitHook({
id: "failing-init",
fn: async () => {
executionOrder.push("global-init");
throw expectedError;
},
});
// Register task init hook that should never be called
lifecycleHooks.registerTaskInitHook("test-task", {
id: "task-init",
fn: async () => {
executionOrder.push("task-init");
return {
foo: "bar",
};
},
});
// Register failure hook to verify it's called
lifecycleHooks.registerGlobalFailureHook({
id: "global-failure",
fn: async ({ error }) => {
executionOrder.push("failure");
expect(error).toBe(expectedError);
},
});
// Register complete hook to verify it's called with error
lifecycleHooks.registerGlobalCompleteHook({
id: "global-complete",
fn: async ({ result }) => {
executionOrder.push("complete");
expect(result).toEqual({
ok: false,
error: expectedError,
});
},
});
const task = {
id: "test-task",
fns: {
run: async (payload: any, params: RunFnParams<any>) => {
executionOrder.push("run");
return {
output: "test-output",
};
},
},
};
const result = await executeTask(task, { test: "data" });
// Verify only the global init hook ran, and failure/complete hooks were called
expect(executionOrder).toEqual(["global-init", "failure", "complete"]);
// Verify the error result
expect(result).toEqual({
result: {
ok: false,
id: "test-run-id",
error: {
type: "BUILT_IN_ERROR",
message: "Init hook error",
name: "Error",
stackTrace: expect.any(String),
},
skippedRetrying: false,
},
});
});
test("should propagate errors from task init hooks", async () => {
const executionOrder: string[] = [];
const expectedError = new Error("Task init hook error");
// Register global init hook that succeeds
lifecycleHooks.registerGlobalInitHook({
id: "global-init",
fn: async () => {
executionOrder.push("global-init");
return {
foo: "bar",
};
},
});
// Register task init hook that throws an error
lifecycleHooks.registerTaskInitHook("test-task", {
id: "task-init",
fn: async () => {
executionOrder.push("task-init");
throw expectedError;
},
});
// Register failure hook to verify it's called
lifecycleHooks.registerGlobalFailureHook({
id: "global-failure",
fn: async ({ error, init }) => {
executionOrder.push("failure");
expect(error).toBe(expectedError);
// Verify we got the global init data
expect(init).toEqual({ foo: "bar" });
},
});
// Register complete hook to verify it's called with error
lifecycleHooks.registerGlobalCompleteHook({
id: "global-complete",
fn: async ({ result, init }) => {
executionOrder.push("complete");
expect(result).toEqual({
ok: false,
error: expectedError,
});
// Verify we got the global init data
expect(init).toEqual({ foo: "bar" });
},
});
const task = {
id: "test-task",
fns: {
run: async (payload: any, params: RunFnParams<any>) => {
executionOrder.push("run");
return {
output: "test-output",
};
},
},
};
const result = await executeTask(task, { test: "data" });
// Verify both init hooks ran, but run wasn't called, and failure/complete hooks were called
expect(executionOrder).toEqual(["global-init", "task-init", "failure", "complete"]);
// Verify the error result
expect(result).toEqual({
result: {
ok: false,
id: "test-run-id",
error: {
type: "BUILT_IN_ERROR",
message: "Task init hook error",
name: "Error",
stackTrace: expect.any(String),
},
skippedRetrying: false,
},
});
});
test("should propagate errors from start hooks", async () => {
const executionOrder: string[] = [];
const expectedError = new Error("Start hook error");
// Register global init hook that succeeds
lifecycleHooks.registerGlobalInitHook({
id: "global-init",
fn: async () => {
executionOrder.push("global-init");
return {
foo: "bar",
};
},
});
// Register global start hook that throws an error
lifecycleHooks.registerGlobalStartHook({
id: "global-start",
fn: async () => {
executionOrder.push("global-start");
throw expectedError;
},
});
// Register task start hook that should never be called
lifecycleHooks.registerTaskStartHook("test-task", {
id: "task-start",
fn: async () => {
executionOrder.push("task-start");
},
});
// Register failure hook to verify it's called
lifecycleHooks.registerGlobalFailureHook({
id: "global-failure",
fn: async ({ error, init }) => {
executionOrder.push("failure");
expect(error).toBe(expectedError);
// Verify we got the init data
expect(init).toEqual({ foo: "bar" });
},
});
// Register complete hook to verify it's called with error
lifecycleHooks.registerGlobalCompleteHook({
id: "global-complete",
fn: async ({ result, init }) => {
executionOrder.push("complete");
expect(result).toEqual({
ok: false,
error: expectedError,
});
// Verify we got the init data
expect(init).toEqual({ foo: "bar" });
},
});
const task = {
id: "test-task",
fns: {
run: async (payload: any, params: RunFnParams<any>) => {
executionOrder.push("run");
return {
output: "test-output",
};
},
},
};
const result = await executeTask(task, { test: "data" });
// Verify init succeeded, start hook failed, and run wasn't called
expect(executionOrder).toEqual(["global-init", "global-start", "failure", "complete"]);
// Verify the error result
expect(result).toEqual({
result: {
ok: false,
id: "test-run-id",
error: {
type: "BUILT_IN_ERROR",
message: "Start hook error",
name: "Error",
stackTrace: expect.any(String),
},
skippedRetrying: false,
},
});
});
});
function executeTask(task: TaskMetadataWithFunctions, payload: any) {